Ich spiele mit einer erweiterbaren Record-Bibliothek, und ich möchte eine Funktion field
schreiben, die entweder als Lens
oder Traversal
basierend darauf funktionieren kann, ob der Symbol
Schlüssel in der Liste der Schlüssel ist oder nicht. Die Art Familie gegeben:Typfamilien können keinen RankN-Typ zurückgeben - Workarounds oder Alternativen?
type family LensOrTraversal key keys s t a b where
LensOrTraversal key '[] s t a b =
Traversal s t a b
LensOrTraversal key (key =: val ': xs) s t a b =
Lens s t a b
LensOrTraversal key (foo =: bar ': xs) s t a b =
LensOrTraversal key xs s t a b
Dieser Code gibt mir eine Fehlermeldung:
/home/matt/Projects/hash-rekt/src/Data/HashRecord/Internal.hs:433:5:
error:
• Illegal polymorphic type: Traversal s t a b
• In the equations for closed type family ‘LensOrTraversal’
In the type family declaration for ‘LensOrTraversal’
Im Idealfall würde ich beide die field
Namen wiederverwenden zu können, wie für Linsen und Querungen, als wäre es erlauben Sie
>>> let testMap = empty & field @"foo" .~ 'a'
>>> :t testMap
HashRecord '["foo" =: Char]
>>> testMap ^. field @"foo"
'a'
>>> testMap ^. field @"bar"
Type error
>>> testMap ^? field @"bar"
Nothing
zu schreiben, die lens
Idiome gemeinsam folgt. Ich kann eine fieldTraversal
Funktion zur Verfügung stellen, die tut, was ich will, aber ich würde lieber den Namen field
überladen, wenn möglich. Wie würdest du diese Einschränkung der Typfamilien umgehen?
Mögliches Duplikat [Illegal polymorph oder qualifiziert Typ mit RankNTypes und TypeFamilies] (http://stackoverflow.com/questions/13846284/illegal-polymorphic-or-qualified-type-using-rankntypes-and-typefamilies) –
@ AntalSpector-Zabusky vielleicht verwandt, aber das ist definitiv kein Duplikat. – leftaroundabout