【发布时间】:2019-05-09 17:52:07
【问题描述】:
我正在尝试了解 RankNTypes。
为什么编译器在这种情况下会抱怨a 不是[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 时发生。任何了解正在发生的事情的指针都会很棒。
谢谢。
【问题讨论】:
-
我不确定您的第二个示例中的
tupleF是什么,但在第一个示例中,错误的原因似乎很清楚。tupleF2需要forall a . a -> b类型的输入 - 即一个可以接受 any 输入并产生固定类型b的输出的函数。我不确定是否存在任何这样的功能,除了const x,其中x :: b- 但length显然不是一个。例如,您不能将length应用于Int -
无论
tupleF是什么,它的参数类型中都没有forall,所以它可以接受任何函数。
标签: haskell typechecking rank-n-types