刚性类型变量的不匹配 [英] Mismatch of rigid type variables
问题描述
下面的Haskell代码在上失败了。无法将类型'a'与'a1'匹配
错误:
bar :: [Int] - > (a - > Int - > a) - > a - > a
bar ns fp ap = snd $ foldl fn(fp,ap)ns
其中fn ::((a-> Int-> a),a) - > Int - > (a-> Int-> a),a)
fn(f,x)i =(fp,(fx(i + length(ns))))
$ c
以下是详细的错误消息:
t.hs:4:24:error:
•无法将类型'a'与'a1'匹配
'a'是一个刚性类型变量,由
绑定类型签名:
bar :: forall a。 [Int] - > (a - > Int - > a) - > a - > a
at t.hs:1:8
'a1'是一个刚性类型变量,由
绑定,类型签名为:
fn :: forall a1。
(a1→> Int→> a1,a1)→> Int - > (a1 - > Int - > a1,a1)
at t.hs:3:15
预期类型:a1 - > Int - > a1
实际类型:a - > Int - > a
•在表达式中:fp
在表达式中:(fp,(fx(i + length(ns))))
在等式'fn'中:
fn(f,x)i =(fp,(fx(i + length(ns))))
•相关绑定包括
x :: a1(绑定在t.hs:4:16)
f :: a1 - > Int - > a1(绑定在t.hs:4:13)
fn ::(a1→> Int→> a1,a1)→> Int - > (a1 - > Int - > a1,a1)
(绑定在t.hs:4:9)
ap :: a(绑定在t.hs:2:11)
fp :: a - > Int - > a(绑定在t.hs:2:8)
bar :: [Int] - > (a - > Int - > a) - > a - > a(绑定在t.hs:2:1)
我以为 fp
函数的参数 bar
具有相同类型的 <$ 中的函数 fn
中的 code> bar
(它们都有类型(a - > Int - > a )),然而 ghci
将它们视为不同的类型( a
和 a1
)。
我尝试删除函数 fn $ c $的类型签名然后代码可以编译成功。
bar :: [Int] - > (a - > Int - > a) - > a - > a
bar ns fp ap = snd $ foldl fn(fp,ap)ns
其中fn(f,x)i =(fp,(fx(i + length(ns))))
我的问题是:为什么额外的类型签名 fn
不起作用?是不是足够智能的类型系统来推断 fp
和 f
可以有相同的类型? (特别是当 fn
位于 bar
范围内时) 。
解决方案 a
> fn 在 bar
的签名中不被识别为相同的 a
。让这个东西起作用的唯一方法是使用 ScopedTypeVariables
。
$ b { - #LANGUAGE ScopedTypeVariables# - }
bar :: forall a。 [Int] - > (a - > Int - > a) - > a - > a
bar ns fp ap = snd $ foldl fn(fp,ap)ns
其中fn ::((a-> Int-> a),a) - > Int - > (a-> Int-> a),a)
fn(f,x)i =(fp,(fx(i + length(ns))))
$ b 或者,您可以不使用 fn
的类型注释,并让编译器推断它。
I have following Haskell code that failed on Couldn't match type ‘a’ with ‘a1’
error:
bar :: [Int] -> (a -> Int -> a) -> a -> a
bar ns fp ap = snd $ foldl fn (fp, ap) ns
where fn :: ((a -> Int -> a), a) -> Int -> ((a -> Int -> a), a)
fn (f, x) i = (fp, (f x (i + length(ns))))
Here's the detailed error message:
t.hs:4:24: error:
• Couldn't match type ‘a’ with ‘a1’
‘a’ is a rigid type variable bound by
the type signature for:
bar :: forall a. [Int] -> (a -> Int -> a) -> a -> a
at t.hs:1:8
‘a1’ is a rigid type variable bound by
the type signature for:
fn :: forall a1.
(a1 -> Int -> a1, a1) -> Int -> (a1 -> Int -> a1, a1)
at t.hs:3:15
Expected type: a1 -> Int -> a1
Actual type: a -> Int -> a
• In the expression: fp
In the expression: (fp, (f x (i + length (ns))))
In an equation for ‘fn’:
fn (f, x) i = (fp, (f x (i + length (ns))))
• Relevant bindings include
x :: a1 (bound at t.hs:4:16)
f :: a1 -> Int -> a1 (bound at t.hs:4:13)
fn :: (a1 -> Int -> a1, a1) -> Int -> (a1 -> Int -> a1, a1)
(bound at t.hs:4:9)
ap :: a (bound at t.hs:2:11)
fp :: a -> Int -> a (bound at t.hs:2:8)
bar :: [Int] -> (a -> Int -> a) -> a -> a (bound at t.hs:2:1)
I was thinking that fp
parameter of function bar
has the same type of f
parameter of function fn
in where
clause of function bar
(they all have type (a -> Int -> a)
), however ghci
treated them as different types (a
and a1
).
I tried to remove type signature of function fn
then the code could be compiled successfully.
bar :: [Int] -> (a -> Int -> a) -> a -> a
bar ns fp ap = snd $ foldl fn (fp, ap) ns
where fn (f, x) i = (fp, (f x (i + length(ns))))
My question is: Why the extra type signature of fn
doesn't work? isn't the type system intelligent enough to infer that both fp
and f
could have same types? (especially when fn
is inside scope of bar
).
解决方案 The a
in the signature for fn
isn't recognized as the same a
in the signature for bar
. The only way to get this thing to work is with ScopedTypeVariables
.
{-# LANGUAGE ScopedTypeVariables #-}
bar :: forall a. [Int] -> (a -> Int -> a) -> a -> a
bar ns fp ap = snd $ foldl fn (fp, ap) ns
where fn :: ((a -> Int -> a), a) -> Int -> ((a -> Int -> a), a)
fn (f, x) i = (fp, (f x (i + length(ns))))
Alternately, you can just not have a type annotation for fn
and let the compiler infer it.
这篇关于刚性类型变量的不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文