让我们在GHCi中进行常规任务

时间:2017-03-23 23:42:08

标签: haskell

之间有什么区别吗?
f x = x + 1

let f x = x + 1

输入GHCi? IIUC,let inGHCi let有效适用于解释器的整个范围。但是,如果base.onclosing 的存在没有区别,那么这条规则的重点是什么?

编辑:使用GHCi 8.0.2版。

3 个答案:

答案 0 :(得分:12)

不,没有区别。

过去,ghci本质上是一个开放式的IO do块。但是无法在这种语法形式中定义新类型,并且需要为每个定义编写let,这被视为令人烦恼的限制,这些限制常常妨碍日常交互使用,因此ghci的语法很慢变得更加宽容。但它只是一种语法变化 - 没有什么深刻的。

但是,有一点需要注意:如果要启动块,则必须明确地执行此操作。例如,

> f [] = 3
> f (x:xs) = 4

相当于

> let f [] = 3
> let f (x:xs) = 4

而不是

> :{
| let f [] = 3
|     f (x:xs) = 4
| :}

因此将成为f定义,它隐藏旧的定义并且仅在非空列表上定义,而您可能想要为单个{f定义两个等式1}}。使用自动阻止模式(:set +m),ghci可以注意到let启动了一个块,并在您键入let时自动为您提供后者,因此:

> let f [] = 3
|     f (x:xs) = 4
|

对于短格式(非let)定义,它不会这样做。

答案 1 :(得分:2)

虽然几个月前就提出了这个问题,但是当我最近开始学习Haskell时,我确实注意到了一些差异。

> :set -Wall
> a = 2
> let a = 3

会出现关于名称阴影 -Wname-shadowing )的警告,而

> :set -Wall
> a = 2
> a = 3

没有。警告似乎只检查明确写入的let语句。

答案 2 :(得分:2)

另一个区别:

λ> x = 1 :: Int
λ> :sprint x
x = _
λ> let x = 1 :: Int
λ> :sprint x
x = 1