在GHCi中:(>表示输出)
data Unit = Unit
let x = Unit
let y = ()
:p x
> x = (_t1::Unit)
:p y
> y = ()
:i ()
> data () = () -- Defined in `GHC.Tuple'
为什么Unit
和()
的行为有所不同?还有其他类型的行为类似于()
,例如Int
和Char
。还有其他类型吗?
令人惊讶的是,当我将()
替换为undefined
时,它的行为与我预期的一样:
let y = undefined :: ()
:p y
y = (_t2::())
答案 0 :(得分:8)
您可能想看看这个GHCi会议:
Prelude> data Unit = Unit deriving Show
Prelude> let x = Unit
Prelude> let x2 = Unit
Prelude> :p x
x = (_t1::Unit)
Prelude> x2
Unit
Prelude> :p x
x = <.:Interactive.Unit>
Prelude> let x3 = Unit
Prelude> :p x3
x3 = <.:Interactive.Unit>
基本上,在x
和x2
定义后,x
是未评估的thunk。强制评估x2
后,我们发现x
也被评估过了。尽管稍后定义,变量x3
永远不会处于未评估的状态。
我相信GHCi正在这里进行一些优化,只为Unit
创建一个thunk。每次使用值构造函数Unit
时,GHCi都会重新使用该thunk。因此,第一次强制使用单个thunk时,通过构造函数定义的每个变量都将显示为已评估状态。
IIRC,小Integer
个文字也使用共享预先评估的thunk:
Prelude> let y3 = 3 :: Integer
Prelude> :p y3
y3 = 3
Prelude> let y4 = 344444444444444 :: Integer
Prelude> :p y4
y4 = (_t3::Integer)