评估(或根本没有)`_`函数参数?

时间:2015-09-05 14:11:56

标签: haskell lazy-evaluation

给定数据类型Foo

Prelude> data Foo a = Foo a

它没有实现Show,因此无法打印。

Prelude> Foo 5
<interactive>:13:1:
    No instance for (Show (Foo a0)) arising from a use of ‘print’

但是,给定一个始终抛出的函数:

Prelude> let f _ = error("bad!")

f可以应用于它。

Prelude> f (Foo 5)
*** Exception: bad!

由于f总是抛出其单个参数,这是否意味着它的参数永远不会被评估,甚至不会被评估为弱头范式?

3 个答案:

答案 0 :(得分:4)

功能&#34; f&#34;正如你所说,永远不会评估它的论点。这与参数是否为&#34; Show&#34;。

的实例无关

你也可以说

Prelude> let f2 _ = "Some value"

Prelude> f2 (Foo 5)
"Some value"

但真正的一点是,即使f2的参数未定义,也不会被评估,因此不会抛出异常

Prelude> f2 undefined
"Some value"

答案 1 :(得分:3)

不,f的参数未被评估。测试此方法的一种简单方法是使用undefined,一旦触摸它就会抛出错误:

>>> undefined
*** Exception: Prelude.undefined

>>> let f _ = "bad"

>>> f undefined
"bad"

但您可以编写一个类似的函数,使用seq评估其对WHNF的参数:

>>> let g a = a `seq` "bad"
>>> g undefined
"*** Exception: Prelude.undefined

BangPatterns

>>> :set -XBangPatterns 
>>> let h !_ = "bad"
>>> h undefined 
"*** Exception: Prelude.undefined

或模式匹配:

>>> let k (Foo _) = "bad"
>>> k undefined 
"*** Exception: Prelude.undefined

但您可以使用~

进行lazy pattern match
>>> let j ~(Foo _) = "bad"
>>> j undefined 
"bad"

答案 2 :(得分:1)

Prelude> let f _ = error("bad!")

Haskell为lazy_ param根本不予评估。

  

要记住的口号是“模式匹配驱动评估”。至   重申重点:

Expressions are only evaluated when pattern-matched

…only as far as necessary for the match to proceed, and no farther!