【发布时间】:2016-12-15 20:18:55
【问题描述】:
我胡闹,在 Haskell 中定义了一个for 函数,如下所示。
for :: (Ord i, Num i) => (i, i, i) -> b -> (i -> b -> b) -> b
for (init, incr, end) initState bodyFn = for' (init, initState) bodyFn
where
-- for' :: (Ord i, Num i) => (i, b) -> (i -> b -> b) -> b
for' (index, state) bodyFn | if incr > 0 then index >= end else index <= end = state
for' (index, state) bodyFn = for' (index + incr, bodyFn index state) bodyFn
效果很好。
> for (1, 1, 10) 0 (\i b -> i+b)
45
我想声明where 函数的类型。 (如您所见,它已被注释掉。)当我删除注释标记时,我收到此错误消息。
Couldn't match expected type ‘i1’ with actual type ‘i’
‘i’ is a rigid type variable bound by
the type signature for:
for :: forall i b.
(Ord i, Num i) =>
(i, i, i) -> b -> (i -> b -> b) -> b
at while.hs:5:8
‘i1’ is a rigid type variable bound by
the type signature for:
for' :: forall i1 b1.
(Ord i1, Num i1) =>
(i1, b1) -> (i1 -> b1 -> b1) -> b1
at while.hs:9:11
• In the second argument of ‘(>=)’, namely ‘end’
In the expression: index >= end
In the expression: if incr > 0 then index >= end else index <= end
• Relevant bindings include
bodyFn :: i1 -> b1 -> b1 (bound at while.hs:10:23)
index :: i1 (bound at while.hs:10:9)
for' :: (i1, b1) -> (i1 -> b1 -> b1) -> b1 (bound at while.hs:10:3)
bodyFn :: i -> b -> b (bound at while.hs:6:34)
end :: i (bound at while.hs:6:19)
incr :: i (bound at while.hs:6:13)
我猜这个问题与for' 函数将其变量之一与for 函数中的变量进行比较这一事实有关——并且还将其变量之一添加到来自for 函数。它们应该属于同一类型。有没有办法这么说?或者有没有其他方法来声明for'函数的类型?
谢谢。
附:我知道我可以将for' 函数声明为顶级函数并将相关变量传递给它,但我想知道是否有办法使用这种结构编写有效的声明。
P.P.S 基本上同样的问题被问到here,但答案是去掉嵌套函数的声明。有什么方法可以写一个有效的吗?
【问题讨论】:
-
刚性类型变量不匹配的答案解决了这个问题。谢谢
标签: haskell