Haskell 将Nat从类型族调用转换为整数
失败于Haskell 将Nat从类型族调用转换为整数,haskell,Haskell,失败于 import Data.Singletons import Data.Singletons.TypeLits type family N t :: Nat where N Int = 42 N String = 9 foo :: (n ~ N t) => t -> Integer foo _ = fromSing (sing :: Sing n) 如何修复它?您的代码有两个问题。首先,(sing::sing n)在作用域中没有n。您需要显式地forall将其纳入
import Data.Singletons
import Data.Singletons.TypeLits
type family N t :: Nat where
N Int = 42
N String = 9
foo :: (n ~ N t) => t -> Integer
foo _ = fromSing (sing :: Sing n)
如何修复它?您的代码有两个问题。首先,
(sing::sing n)
在作用域中没有n
。您需要显式地forall
将其纳入范围
第二,如果你想唱歌,你需要这样说。GHC不知道也从不检查所有t
的nt
是否为SingI
,顺便说一句,这实际上不是真的:N Bool
有种类Nat
,但没有SingI(N Bool)
因此,解决方案是:
• Could not deduce: DemoteRep * ~ Integer
from the context: n ~ N t
bound by the type signature for:
foo :: n ~ N t => t -> Integer
at mini.hs:16:1-32
• In the expression: fromSing (sing :: Sing n)
In an equation for ‘foo’: foo _ = fromSing (sing :: Sing n)
或使用类型应用程序:
foo :: forall t. SingI (N t) => t -> Integer
foo _ = fromSing (sing :: Sing (N t))
谢谢,安德拉斯。现在有道理了。我不明白的是错误信息。ghc不应该抱怨n在Sing n中未绑定吗?@BrunoMartinez ghc将未绑定的类型变量视为上下文中的新变量,并允许您在以后的类型注释中引用它们。因此,它认为
n
是Sing n
一个与foo
签名中的n
无关的新变量。
foo :: forall t. SingI (N t) => t -> Integer
foo _ = fromSing (sing @_ @(N t))