dsp*_*pyz 2 constructor haskell types pattern-matching lazy-evaluation
如果我对一个类型只有一个构造函数的表达式进行模式匹配,那还是会强制运行时将表达式计算为WHNF吗?
我做了一个似乎表明它没有评估的实验:
Prelude> data Test = Test Int Int
Prelude> let errorpr () = error "Fail"
Prelude> let makeTest f = let (x,y) = f () in Test x y
Prelude> let x = makeTest errorpr
Prelude> let Test z1 z2 = x
Prelude> :sprint z1
z1 = _
Prelude> :sprint z2
z2 = _
Prelude> :sprint x
x = _
Run Code Online (Sandbox Code Playgroud)
我本来希望得到一个错误或:sprint x得到
x = Test _ _
Run Code Online (Sandbox Code Playgroud)
但事实并非如此.
显然我不明白"让"是如何运作的.请参阅以下答案
Prelude> let x = makeTest errorpr
Prelude> let Test z1 z2 = x
Run Code Online (Sandbox Code Playgroud)
最后一行不会强制评估任何内容:其中的模式let是(隐式)惰性模式(也称为无可辩驳的模式).试试吧
Prelude> let x = makeTest errorpr
Prelude> case x of Test z1 z2 -> "hello!"
Prelude> :sprint x
Run Code Online (Sandbox Code Playgroud)
你应该观察类似的事情Test _ _,因为模式case不是懒惰的.通过比较,
Prelude> let x = makeTest errorpr
Prelude> case x of ~(Test z1 z2) -> "hello!" -- lazy pattern!
Prelude> :sprint x
Run Code Online (Sandbox Code Playgroud)
应该打印_,就像使用时一样let.
以上适用于data类型.相反,newtypes不提升内部类型,而是直接使用相同的表示.也就是说,newtype值构造和模式匹配在运行时是无操作:它们在类型检查后大致被编译器擦除.