cro*_*eea 6 reflection haskell type-inference data-kinds
我在让GHC在一个显而易见的地方推断类型时遇到了问题.下面是一个完整的片段,展示了这个问题.
{-# LANGUAGE DataKinds, ScopedTypeVariables, KindSignatures, TypeOperators, GADTs #-}
import Data.Reflection
import Data.Proxy
import Data.Tagged
-- heterogeneous list, wrapping kind [*] as *
data HList :: [*] -> * where
HNil :: HList '[]
HCons :: a -> HList as -> HList (a ': as)
main = test2
test1 = do
let x = HCons 3 HNil :: HList '[Int]
c = case x of (HCons w HNil) -> w
print c
test2 = reify True (\(_::Proxy a) -> do
let x = HCons (Tagged 3) HNil :: HList '[Tagged a Int]
c = case x of (HCons w HNil) -> w
print $ untag (c :: Tagged a Int))
Run Code Online (Sandbox Code Playgroud)
在test1,我可以打印c而不给出c明确的类型,就像我期望的那样.类型c由显式签名推断x:即,HListhas类型中的第一个元素Int.
在test2,然而,在明确的签名c是必需的.如果我只是print $ untag c在test2,我得到
Test.hs:22:32:
Couldn't match type `s0' with `s'
`s0' is untouchable
inside the constraints (as ~ '[] *)
bound at a pattern with constructor
HNil :: HList ('[] *),
in a case alternative
`s' is a rigid type variable bound by
a type expected by the context:
Reifies * s Bool => Proxy * s -> IO ()
at Test.hs:19:9
Expected type: Tagged * s0 Int
Actual type: a
In the pattern: HNil
In the pattern: HCons w HNil
In a case alternative: (HCons w HNil) -> w
Run Code Online (Sandbox Code Playgroud)
为什么GHC不能推断的类型c从给予明确的类型x为test1?
我发现这些错误与 let-绑定有关...尽管我不知道确切的原因,也不知道它是否实际上是 GHC 中的错误。解决方法是使用 case 语句:
test4 = reify True $ \ (_::Proxy a) -> do
let x = HCons (Tagged 4) HNil :: HList '[Tagged a Int]
c = case x of (HCons w HNil) -> w
print $ untag (c :: Tagged a Int)
test5 = reify True $ \ (_::Proxy a) -> do
case HCons (Tagged 5) HNil :: HList '[Tagged a Int] of
HCons w HNil -> print $ untag w
Run Code Online (Sandbox Code Playgroud)