功能无法匹配类型

Oru*_*rup 6 haskell types type-inference

我的功能如下:

    foo :: Int -> a -> [a]
    foo n v = bar n
      where
        bar :: Int -> [a]
        bar n = take n $ repeat v
Run Code Online (Sandbox Code Playgroud)

使用ghci报告此错误:

    Couldn't match type `a' with `a1'
          `a' is a rigid type variable bound by
              the type signature for foo :: Int -> a -> [a] at hs99.hs:872:1
          `a1' is a rigid type variable bound by
              the type signature for bar :: Int -> [a1] at hs99.hs:875:9
    Expected type: [a1]
        Actual type: [a]
    In the expression: take n $ repeat v
    In an equation for `bar': bar n = take n $ repeat v
Run Code Online (Sandbox Code Playgroud)

如果删除bar的类型声明,则可以编译代码而不会出错.那么这里吧的正确类型声明是什么?并且为什么会发生错误,因为bar的类型声明比bar的定义更通用(在foo中绑定到某种类型)?

谢谢你的帮助!

dav*_*420 9

a

foo :: Int -> a -> [a]
Run Code Online (Sandbox Code Playgroud)

ain

    bar :: Int -> [a]
Run Code Online (Sandbox Code Playgroud)

是具有相同名称的不同类型变量.

要获得您期望的行为,请打开ScopedTypeVariables扩展(例如,通过插入{-# LANGUAGE ScopedTypeVariables #-}源文件的顶部),并将类型签名更改foo

foo :: forall a. Int -> a -> [a]
Run Code Online (Sandbox Code Playgroud)

如果未启用ScopedTypeVariables,就好像您的原始代码是这样编写的:

foo :: forall a. Int -> a -> [a]
foo n v = bar n
  where
    bar :: forall a. Int -> [a]
    bar n = take n $ repeat v
Run Code Online (Sandbox Code Playgroud)

如果省略类型注释,那么ghci隐式使用ScopedTypeVariables是不正确的bar.

相反,你给出的bar与ghci类型冲突的类型注释- 你断言bar有一个ghci知道它不能拥有的类型.

删除类型注释时,将删除冲突.

ScopedTypeVariables更改您提供的类型注释的含义.它不会影响ghc如何推断类型.