2017-05-03 16 views
4

私は拡張可能なレコードライブラリで遊んでいますが、私は、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。このタイプのファミリの制限を回避するにはどうしますか?

+0

[RankNTypesとTypeFamiliesを使用した不正な多型または修飾型]の重複の可能性あり(http://stackoverflow.com/questions/13846284/illegal-polymorphic-or-qualified-type-using-rankntypes-and-typefamilies) –

+0

@ AntalSpector-Zabuskyはおそらく関連していますが、これは間違いなく重複していません。 – leftaroundabout

答えて

4

レンズだけそのランク2数量詞は、完全な制約を使用しない、すでにトラバーサルである(それは単にFunctor、ないApplicativeが必要です)。

type Lens s t a b  = ∀ f . Functor f  => (a -> f b) -> s -> f t 
type Traversal s t a b = ∀ f . Applicative f => (a -> f b) -> s -> f t 

それはあなたがあなたのタイプの家族を導入すべきである。この制約のレベルである。そして、

import GHC.Exts (Constraint) 
type family FieldOpticConstraint key keys :: (* -> *) -> Constraint where 
    FieldOpticConstraint key '[] = Applicative 
    FieldOpticConstraint key (key =: val ': xs) = Functor 
    FieldOpticConstraint key (_ ': xs) = FieldOpticConstraint key xs 

field制約を常にカスタムランク2署名をLensOrTraversalが得られますが、ないはずタイプファミリによって決定されます。

+0

ニース!含意の制約があっただけでは、「少なくとも「トラバーサル」でなければならない」といったような気の利いた表現が可能でした。私はそのようなアイデアについてある時を尋ねた。明示的な辞書操作なしでコンセプトを表現する手間がかかりますか? – dfeuer

+0

ピュー、分かりません。任意の多形型からこのような制約を取得しようとすると、ワームの可能性があると思われます。これは決定可能なのでしょうか? – leftaroundabout

+0

ニース!これは私の問題を解決しました。さて、私はちょうどその値のレベルでその情報を大文字にする方法を把握する必要があります... – ephrion

関連する問題