首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在haskell中使用作用域类型变量和y组合符时出现奇怪的错误

在haskell中使用作用域类型变量和y组合符时出现奇怪的错误
EN

Stack Overflow用户
提问于 2011-05-04 22:59:38
回答 3查看 404关注 0票数 2

所以我尝试了y-combinator和匿名函数,我遇到了这个奇怪的错误:

代码语言:javascript
复制
Couldn't match expected type `t0 -> t1 -> t2'
            with actual type `forall b. b -> [b] -> [b]'
The lambda expression `\ (n :: Int) newVal xs -> ...'
has three arguments,
but its type `Int -> forall b. b -> [b] -> [b]' has only one

(source code that creates the errorversion that I eventually got working)

如果I为modify the types slightly to avoid Rank N polymorphism (use forall b. Int -> b -> [b] -> [b]),则错误类似:

代码语言:javascript
复制
Couldn't match expected type `t0 -> t1 -> t2 -> t3'
            with actual type `forall b. Int -> b -> [b] -> [b]'
The lambda expression `\ (n :: Int) newVal xs -> ...'
has three arguments,
but its type `forall b. Int -> b -> [b] -> [b]' has none

有人能给我解释一下为什么forall b. b -> [b] -> [b]没有参数吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-05-05 02:17:37

由于您使用的是GHC7,这似乎与http://hackage.haskell.org/trac/ghc/ticket/4347中报告的bug具有相同的根本原因。虽然那个bug报告谈到了非预测性多态性,但它似乎最有可能出现在更高级别的多态性中的统一问题中。在您的例子中,它是由您放置的forall触发的,这使得该类型在语法上的等级为2。

请注意,这并不是一个真正的bug。提供的进一步澄清清楚地表明这是预期的行为,因为类型的多态实例化,包括排名-N类型和不可预测类型,是不被推断的。仔细添加类型签名可以使其正常工作。

但由于该类型的目的不是为了更高的级别,在您的情况下,最好的方法就是去掉它。

票数 2
EN

Stack Overflow用户

发布于 2011-05-04 23:46:18

你是想要

代码语言:javascript
复制
forall b. Int -> b -> [b] -> [b]

或者说真的

代码语言:javascript
复制
Int -> forall b . b -> [b] -> [b]

我会读到后者:一个函数,它接受一个Int,并返回一些不透明的东西,很可能不是你想的那样。

票数 0
EN

Stack Overflow用户

发布于 2011-05-04 23:49:45

我的猜测是你写错了类型。

删除类型注释会有一些帮助,从而减少令人困惑的错误:

代码语言:javascript
复制
A.hs:7:76:
    Occurs check: cannot construct the infinite type: a0 = [a0]
    In the third argument of `replaceNth', namely `arg'
    In the expression: replaceNth m (replaceNth n v (arg !! m)) arg

所以

代码语言:javascript
复制
 \m n v arg -> replaceNth m (replaceNth n v (arg !! m)) arg

已经有问题了。

排名N个类型和词法作用域类型变量

通过使用不在最外层位置的forall,您已经遇到了rank types。内部b上的forall说明它必须是不透明的、多态的,并且与b类型的其他用法无关。这可能不是您想要做的事情。

这与词法作用域类型变量略有不同,后者也可以由最外层的forall引入,如described here

通过删除(我认为)非最外层位置中的错误forall,您将得到简单得多的类型错误。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5885479

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档