fI am learning singletons
package these days and have encountered some difficulties. I would like to translate the following Idris
code into Haskell but failed:
data Header : Type where
MkHeader : (ver : Int) -> (val : Int) -> Header
headerToType : Header -> Type
headerToType (MkHeader ver val) = case ver of
1 => Int
2 => String
_ => ()
data Msg : Type -> Type where
MkMsg : (header : Header)
-> (body : headerToType header)
-> Msg (headerToType header)
I know that I can use type families to write a “function” on types and get the runtime witness of a singleton type. But I still can not finish it:
data Header = Header
{ headerVer :: Int
, headerVal :: Int
}
type family TF (n :: Nat) where
TF 0 = Int
TF 1 = String
TF a = ()
data Msg a where
MkMsg :: (a ~ TF n) => SNat n -> a -> Msg a -- should we add the constraint here?
{-
realMkMsg :: Header -> a -> Msg a -- or (forall a. a -> Msg a) ?
realMkMsg h = withSomeSing (fromIntegral (headerVer h))
(\sn payload -> MkMsg sn payload) -- error, 'a' is a rigid type var!
-}
So my questions are:
- Is GHC’s type system powerful enough to write an equivalent version of the Idris code? If so, how can I finish it?
- What is the exact strength of GHC’s type system? I have heard that it is System F plus coercions. Does it fit the actual GHC implementation nowadays well? I also would like to know the meaning of “coercions” and its contribution to the whole type system.