lambda 函数的 Haskell 类型推断(在地图中) [英] Haskell type inference for lambda functions (in map)

查看:40
本文介绍了lambda 函数的 Haskell 类型推断(在地图中)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

示例 1

以下没有类型声明的定义会抛出错误:

f :: Eq t =>(t,t) ->Bool -- 省略这一行会导致错误f = \(x,y) ->x==y

(我知道这个函数可以写得更短,但这不是重点.)

示例 2

另一方面,在使用 map 的函数中使用 same lambda 函数确实可以工作而不会产生错误:

 g l = map (\(x,y) -> x==y) l

(举个例子:g [(3,4),(5,5),(7,6)] 会产生 [False,True,False]代码>

示例 3

下面的代码也很好,它似乎与上面的原始 f 完全一样.在这里,类型推断似乎有效.

 f' (x,y) = x==y

问题

所以我的问题是:为什么我们在第一种情况下需要类型声明,而在第二种和第三种情况下不需要?

解决方案

如果您使用:

{-# LANGUAGE NoMonomorphismRestriction #-}f = \(x,y) ->x==y

你不会得到错误.

更新

Haskell Wiki 页面关于 Monomorphism Restriction (链接) 提供了一些关于为什么这些定义被区别对待的详细信息:

f1 x = 显示 xf2 = \x ->显示 x

<块引用>

第一个和第二个版本的区别在于第一个版本通过函数绑定"绑定 x(参见 Haskell 2010 报告的 4.4.3 节),因此不受限制,但第二个版本没有.一个被允许而另一个不被允许的原因是很明显共享 f1 不会共享任何计算,而不太清楚共享 f2 将具有相同的效果.如果这看起来是任意的,那是因为它是.很难设计一个客观规则,禁止主观意外行为.有些人即使做的很合理,也会违反规则.

Example 1

Following definition without the type declaration will throw an error:

f :: Eq t => (t,t) -> Bool  -- omiting this line will result in an error
f = \(x,y) -> x==y

(I know this function can be written shorter, but this is not the point here.)

Example 2

On the other hand using the same lambda function in a function using map does work without producing an error:

 g l = map (\(x,y) -> x==y) l

(Just as an illustration: g [(3,4),(5,5),(7,6)] will produce [False,True,False]

Example 3

Also following code is perfectly fine and it seems to do exactly the same as the original f from above. Here the type inference seems to work.

 f' (x,y) = x==y

Question

So my question is: Why do we need a type declaration in the first case, but not in the second and in the third?

解决方案

If you use:

{-# LANGUAGE NoMonomorphismRestriction #-}

f = \(x,y) -> x==y

you won't get the error.

Update

The Haskell Wiki page on Monomorphism Restriction (link) offers some details on why these definitions are treated differently:

f1 x = show x

f2 = \x -> show x

The difference between the first and second version is that the first version binds x via a "function binding" (see section 4.4.3 of the Haskell 2010 Report), and is therefore unrestricted, but the second version does not. The reason why one is allowed and the other is not is that it's considered clear that sharing f1 will not share any computation, and less clear that sharing f2 will have the same effect. If this seems arbitrary, that's because it is. It is difficult to design an objective rule which disallows subjective unexpected behaviour. Some people are going to fall foul of the rule even though they're doing quite reasonable things.

这篇关于lambda 函数的 Haskell 类型推断(在地图中)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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