シンボルを使用して型レベルでタグ付けされたアイテムを格納するデータ構造を作成したいとします。この:あなたはコンパイラがfrom' _ Nil
定義(??なぜそれが、やり方によって、それは止めるようにする方法があるん)しかし、私が本当に欲しかっを供給していないために私を警告しているという事実を無視した場合慣用論理型等価使用法(シングルトン)
data Store e (ss :: [Symbol]) where
Nil :: Store e '[]
Cons :: e s -> Store e ss -> Store e (s ': ss)
data HasElem (a :: k) (as :: [k]) where
AtHead :: HasElem a (a ': as)
InTail :: HasElem a as -> HasElem a (b ': as)
class HasElemC (a :: k) (as :: [k]) where hasElem :: HasElem a as
instance HasElemC {OVERLAPPING} a (a ': as) where hasElem = AtHead
instance HasElemC a as => HasElemC a (b ': as) where hasElem = InTail hasElem
from :: HasElemC s ss => Store e ss -> e s
from = from' hasElem
from' :: HasElem s ss -> Store e ss -> e s
-- from' _ Nil = undefined
from' h (Cons element store) = case h of
AtHead -> element
InTail h' -> from' h' store
はちょっと、作品初めに自分の型レベルコードを書くのではなく、シングルトンライブラリを慣用的な方法で使用することでした。このような何か:
import Data.Singletons.Prelude.List
data Store e (ss :: [Symbol]) where
Nil :: Store e '[]
Cons :: Sing s -> e s -> Store e ss -> Store e (s ': ss)
from :: Elem s ss ~ True => Store e ss -> e s
from (Cons evidence element nested) = ???
悲しいことに、私は命題平等にコンテキストを変換する方法を見つけ出すことができませんでした。どのように私は何をしようとしているシングルトンライブラリからのビルディングブロックを使用することができますか?
[email protected]、[email protected]
'storeHead :: Store e(s ':ss) - > es'と' storeTail :: Store e(s ':ss) - > Store e ssという関数を追加することで 'from' 'AtHead'または' InTail'とマッチした後に店で使用してください。 – cchalmers
2つの 'HasElemC'インスタンスが重なっています。GHCは、証明検索を行う際に前提条件をチェックしないので、HasElemC制約を解除することが不可能であることがわかります。幸いなことに、タイプファミリーと 'UndecidableInstances'(https://wiki.haskell.org/GHC/AdvancedOverlap)を使ったよく知られたトリックがあります。 (実際、これはブール型のファミリーの数少ない良い使い方の1つです。) –
cchalmersさん、ありがとうございました。 ありがとう、Benjamin。私の場合、オーバーラップは問題ありません:私はssで多相関数を必要としません。私は将来彼らを必要とするかもしれませんが。 – NioBium