Ich verwende den folgenden Code für einen Datensatz, der ein Feld '_scene' vom Typ SceneGraph hat. Ich habe Linsen dafür mit makeLenses erstellt.
%Vor%Ich erhalte den Fehler:
%Vor%Aber ich verstehe nicht, warum SceneGraph eine Instanz von Monoid sein muss, um diese Linse zu benutzen.
Wahrscheinlich möchten Sie entweder (^?)
oder vielleicht (^..)
(nicht operierende Namen: preview
, toListOf
).
Wenn Sie ein Lens
(oder ein Getter
, Iso
, Equality
usw.) haben, bezieht es sich immer auf genau ein Element. Sie können also das einfache alte (^.)
(Name des Nicht-Operators: view
) verwenden. Wenn Sie ein Traversal
(oder ein Fold
, Prism
usw.) haben, kann es sich auf 0 oder mehr Elemente beziehen.
Daher muss es eine Möglichkeit geben, sie zu kombinieren, wenn es mehr als eins gibt, oder einen Standardwert, wenn nichts vorhanden ist. Dies geschieht mit der Einschränkung Monoid
. toListOf
gibt Ihnen eine Liste aller Werte; preview
gibt Ihnen entweder Nothing
oder Just
den ersten Wert.
Sie haben die Typen für keine der Funktionen angegeben, die Sie verwenden, daher kann ich nicht genau sagen, was Sie beabsichtigt haben. Ich vermute, dass scene
möglicherweise fehlschlägt, weil Sie makeLenses
mit einem Summentyp verwendet haben, der scene
nicht in jedem Summand definiert. In diesem Fall möchten Sie wahrscheinlich (^?)
verwenden und den Fall Nothing
behandeln. Aber es könnte etwas anderes sein.
Siehe auch meine Antwort auf diese Frage (und diese Frage von gestern! Dies scheint ein beliebtes Thema zu sein."
Ich gehe davon aus, dass Sie Ed Kmetts Linsenbibliothek verwenden, es wäre hilfreich, wenn Sie auch die Version, die Sie verwenden, und die Importe veröffentlichen können. Es scheint auch, dass es zwei Versionen von (^.) Gibt, die in dieser Linsenbibliothek unterstützt werden, eine mit einem Getter und eine mit einer Faltung, wobei die Faltungsversion eine Instanz von Monoid erfordert: (^.) :: Monoid r = & gt; s - & gt; Falten s r - & gt; r
Bearbeiten: Ich wette, dass Sie Control.Lens.Fold versehentlich importiert haben