`_` 函数参数的评估(或根本 none)?
Evaluation (or none at all) of `_` Function Argument?
给定数据类型,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
总是为其单个参数抛出异常,这是否意味着它的参数永远不会被评估,甚至不会对 Weak Head Normal Form 进行评估?
不,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
>>> :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"
Prelude> let f _ = error("bad!")
Haskell 是 lazy,_
参数根本没有计算。
The slogan to remember is “pattern matching drives evaluation”. To
reiterate the important points:
Expressions are only evaluated when pattern-matched
…only as far as necessary for the match to proceed, and no farther!
函数 "f" 从不计算它的参数,正如你所说的。这与参数是否是 "Show".
的实例无关
你也可以说
Prelude> let f2 _ = "Some value"
Prelude> f2 (Foo 5)
"Some value"
但真正的重点是,即使 f2 的参数未定义,它也不会被求值,因此不会抛出异常
Prelude> f2 undefined
"Some value"
给定数据类型,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
总是为其单个参数抛出异常,这是否意味着它的参数永远不会被评估,甚至不会对 Weak Head Normal Form 进行评估?
不,f
的参数未被评估。一个简单的测试方法是使用 undefined
,一旦它被触摸就会抛出一个错误:
>>> undefined
*** Exception: Prelude.undefined
>>> let f _ = "bad"
>>> f undefined
"bad"
但您可以编写一个类似的函数,使用 seq
:
>>> let g a = a `seq` "bad"
>>> g undefined
"*** Exception: Prelude.undefined
>>> :set -XBangPatterns
>>> let h !_ = "bad"
>>> h undefined
"*** Exception: Prelude.undefined
或模式匹配:
>>> let k (Foo _) = "bad"
>>> k undefined
"*** Exception: Prelude.undefined
但您可以使用 ~
:
>>> let j ~(Foo _) = "bad"
>>> j undefined
"bad"
Prelude> let f _ = error("bad!")
Haskell 是 lazy,_
参数根本没有计算。
The slogan to remember is “pattern matching drives evaluation”. To reiterate the important points:
Expressions are only evaluated when pattern-matched …only as far as necessary for the match to proceed, and no farther!
函数 "f" 从不计算它的参数,正如你所说的。这与参数是否是 "Show".
的实例无关你也可以说
Prelude> let f2 _ = "Some value"
Prelude> f2 (Foo 5)
"Some value"
但真正的重点是,即使 f2 的参数未定义,它也不会被求值,因此不会抛出异常
Prelude> f2 undefined
"Some value"