了解 Haskell RankNTypes 错误消息
Understanding Haskell RankNTypes Error message
我正在尝试了解 RankNTypes。
为什么编译器在这种情况下会抱怨 can a
NOT be [a]
?
> :{
> | tupleF2 :: (forall a . a -> b) -> (a1, a2) -> (b, b)
> | tupleF2 elemF2 (x, y) = (elemF2 x, elemF2 y)
> | :}
> :t tupleF2 tupleF2 :: (forall a. a -> b) -> (a1, a2) -> (b, b)
> :t tupleF2 length
<interactive>:1:9: error:
• Couldn't match type ‘a’ with ‘[a0]’
‘a’ is a rigid type variable bound by
a type expected by the context:
forall a. a -> Int
at <interactive>:1:1-14
Expected type: a -> Int
Actual type: [a0] -> Int
• In the first argument of ‘tupleF2’, namely ‘length’
In the expression: tupleF2 length
虽然下面的类型检查没问题? t
可以与 t a
.
> :t tupleF length
tupleF length :: Foldable t => (t a, t a) -> (Int, Int)
:t tupleF
tupleF :: (t -> b) -> (t, t) -> (b, b)
上面的编译失败是否只发生在启用RankNTypes
的情况下。任何了解正在发生的事情的指示都会很棒。
谢谢。
forall a . a -> b
是函数 f
的类型,它可以将任何类型 a
的值转换为 b
类型的某个值。请注意 f
必须准备好接受任何输入,即所有这些都必须输入 check
f ()
f 32
f True
f 'a'
f "hello"
f (True, [2], False)
length
不满足要求,例如length ()
类型错误——length
想要一个可折叠的(如列表)作为输入,而 ()
不正确。
因此,tupleF2 length
类型错误。
实用的,注意f
只能是一个常量函数,比如
f x = True -- assuming b = Bool
确实,parametricity 保证只有常量函数可以具有类型 forall a . a -> b
。您可以尝试 tupleF2 (const True) ((),"hello")
并获得 (True, True)
.
我正在尝试了解 RankNTypes。
为什么编译器在这种情况下会抱怨 can a
NOT be [a]
?
> :{
> | tupleF2 :: (forall a . a -> b) -> (a1, a2) -> (b, b)
> | tupleF2 elemF2 (x, y) = (elemF2 x, elemF2 y)
> | :}
> :t tupleF2 tupleF2 :: (forall a. a -> b) -> (a1, a2) -> (b, b)
> :t tupleF2 length
<interactive>:1:9: error:
• Couldn't match type ‘a’ with ‘[a0]’
‘a’ is a rigid type variable bound by
a type expected by the context:
forall a. a -> Int
at <interactive>:1:1-14
Expected type: a -> Int
Actual type: [a0] -> Int
• In the first argument of ‘tupleF2’, namely ‘length’
In the expression: tupleF2 length
虽然下面的类型检查没问题? t
可以与 t a
.
> :t tupleF length
tupleF length :: Foldable t => (t a, t a) -> (Int, Int)
:t tupleF
tupleF :: (t -> b) -> (t, t) -> (b, b)
上面的编译失败是否只发生在启用RankNTypes
的情况下。任何了解正在发生的事情的指示都会很棒。
谢谢。
forall a . a -> b
是函数 f
的类型,它可以将任何类型 a
的值转换为 b
类型的某个值。请注意 f
必须准备好接受任何输入,即所有这些都必须输入 check
f ()
f 32
f True
f 'a'
f "hello"
f (True, [2], False)
length
不满足要求,例如length ()
类型错误——length
想要一个可折叠的(如列表)作为输入,而 ()
不正确。
因此,tupleF2 length
类型错误。
实用的,注意f
只能是一个常量函数,比如
f x = True -- assuming b = Bool
确实,parametricity 保证只有常量函数可以具有类型 forall a . a -> b
。您可以尝试 tupleF2 (const True) ((),"hello")
并获得 (True, True)
.