这是一个简短的例子。我想知道为什么在TypeClass示例中我没有明确说forall
而在没有forall
的函数定义中它无法编译:
Couldn't match kind ‘Nat’ with ‘*’
When matching types
proxy0 :: Nat -> *
Proxy :: * -> *
Expected type: proxy0 n0
Actual type: Proxy p0
In the first argument of ‘natVal’, namely ‘(Proxy :: Proxy p)’
In the second argument of ‘($)’, namely ‘natVal (Proxy :: Proxy p)’
In the first argument of ‘(++)’, namely
‘(show $ natVal (Proxy :: Proxy p))’
代码:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RoleAnnotations #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeFamilies #-}
data Container (p :: Nat) (k :: Nat) = Container { first :: [Int], second :: [Int] }
instance (KnownNat p, KnownNat k) => Show (Container p k) where
show c = "Container " ++ (show $ natVal (Proxy :: Proxy p)) ++
" " ++ (show $ natVal (Proxy :: Proxy k))
showMe :: forall p k . (KnownNat p, KnownNat k) => Container p k -> String
showMe c = "Container " ++ (show $ natVal (Proxy :: Proxy p)) ++
" " ++ (show $ natVal (Proxy :: Proxy k))
答案 0 :(得分:5)
ScopedTypeVariables
将实例头中的类型变量带入实例主体的范围,而没有明确的forall
。类型签名不会发生这种情况;相反,您必须使用forall
将p
和k
纳入showMe
定义的范围。