私は拡張可能なレコードライブラリで遊んでいますが、私は、Symbol
キーがキーのリストにあるかどうかに基づいてLens
またはTraversal
のいずれかとして機能する関数field
を書きたいと思っています。型家族が与えられます。タイプファミリーはRankNタイプを返すことはできません - 回避策または代替案?
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
このコードは私にエラーを与える:
理想的/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’
、私はそれと同じように、レンズとトラバーサルの両方のためにfield
名を再利用できるようにしたいのですが書くことができます
>>> let testMap = empty & field @"foo" .~ 'a'
>>> :t testMap
HashRecord '["foo" =: Char]
>>> testMap ^. field @"foo"
'a'
>>> testMap ^. field @"bar"
Type error
>>> testMap ^? field @"bar"
Nothing
lens
イディオムの後に続きます。私は、私が欲しいことをするfieldTraversal
関数を提供することができますが、可能であれば、名前をオーバーロードすることを好むでしょうfield
。このタイプのファミリの制限を回避するにはどうしますか?
[RankNTypesとTypeFamiliesを使用した不正な多型または修飾型]の重複の可能性あり(http://stackoverflow.com/questions/13846284/illegal-polymorphic-or-qualified-type-using-rankntypes-and-typefamilies) –
@ AntalSpector-Zabuskyはおそらく関連していますが、これは間違いなく重複していません。 – leftaroundabout