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)
失败
• 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)
我该如何解决?
答案 0 :(得分:3)
您的代码存在两个问题。首先,(sing :: Sing n)
在范围内没有n
。您需要明确forall
才能将其纳入范围。
其次,如果你想要SingI
,你需要说出来。 GHC不知道并永远不会检查所有N t
的{{1}}是SingI
,这实际上并非如此:t
有N Bool
但是Nat
没有SingI (N Bool)
。
因此,解决方案:
foo :: forall t. SingI (N t) => t -> Integer
foo _ = fromSing (sing :: Sing (N t))
或者使用类型应用程序:
foo :: forall t. SingI (N t) => t -> Integer
foo _ = fromSing (sing @_ @(N t))