I want to create a data structure to store items tagged on type level using Symbol. This:
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
kinda works, if you neglect the fact that compiler warns me for not supplying from' _ Nil
definition (why does it, by the way? is there a way to make it stop?) But what I really wanted to do in the beginning was to use singletons library in idiomatic fashion, instead of writing my own type-level code. Something like this:
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) = ???
Sadly I could not figure out how to convert the context to a propositional equality. How can you use building blocks from singletons library to do what I'm trying to do?
ghc@7.10.3, singletons@2.1