刚性类型变量的不匹配 [英] Mismatch of rigid type variables

查看:106
本文介绍了刚性类型变量的不匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的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))))



以下是详细的错误消息:

  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

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆