之间有什么区别吗?
f x = x + 1
和
let f x = x + 1
输入GHCi? IIUC,let
in
内GHCi
let
有效适用于解释器的整个范围。但是,如果base.onclosing
的存在没有区别,那么这条规则的重点是什么?
编辑:使用GHCi 8.0.2版。
答案 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