是运营商&&哈斯克尔严格吗?

时间:2011-09-30 15:21:22

标签: haskell logical-operators strictness

例如,我有一个操作fnB :: a -> Bool,在fnA :: Bool返回False之前没有任何意义。在C中,我可以在一个if块中组合这两个操作:

if( fnA && fnB(a) ){ doSomething; }

和C将保证fnBfnA返回false之前不会执行。

但是Haskell是懒惰的,并且通常不能保证首先执行什么操作,直到我们不使用seq$!或其他东西来使我们的代码严格。一般来说,这就是我们需要快乐的事情。但是使用&&运算符,我希望在fnB返回结果之前不会评估fnA。 Haskell是否为&&提供了这样的保证?即使fnB返回False,Haskell也会评估fnA吗?

4 个答案:

答案 0 :(得分:32)

只有当第一个参数为(&&)时,函数True的第二个参数才是严格的。它的第一个论点总是严格的。这种严格/懒惰是保证评估顺序的原因。

因此它的行为与C完全相同。不同之处在于,在Haskell中,(&&)是一个普通的函数。在C中,这是不可能的。

  

但是Haskell是懒惰的,并且通常不能保证首先执行什么操作,直到我们不使用seq,$!或其他东西来严格执行我们的代码。

这不正确。事实更深刻。

严格的崩溃课程

我们知道(&&)的第一个参数是严格的,因为:

⊥ && x = ⊥

这里,⊥类似undefined或无限循环(⊥发音为“bottom”)。我们也知道(False &&)在第二个参数中是非严格的:

False && ⊥ = False

它不可能评估它的第二个参数,因为它的第二个参数是⊥,它不能被评估。但是,函数(True &&)在其第二个参数中是严格的,因为:

True && ⊥ = ⊥

因此,我们说(&&)在第一个参数中始终是严格的,而在第二个参数中仅在第一个参数为True时才严格。

评估顺序:

对于(&&),其严格性属性足以保证执行顺序。情况并非总是如此。例如,(+) :: Int -> Int -> Int在两个参数中始终是严格的,因此可以首先计算任一参数。但是,您只能通过在IO monad中捕获异常,或者使用unsafe函数来区分异常。

答案 1 :(得分:5)

正如其他人所指出的,自然(&&)在其中一个论点中是严格的。按照标准定义,它的第一个论点是严格的。您可以使用flip来翻转语义。

作为补充说明:请注意(&&)的参数不会产生副作用,因此只有两个原因可以解释x && y yy是否严格的原因:

  • 效果:如果y需要很长时间才能计算。
  • 语义:如果您希望{{1}}可以在底部。

答案 2 :(得分:1)

  

Haskell很懒,而且一般来说,无法保证首先执行什么操作

不完全。 Haskell是(除了unsafePerformIOIO的实现),并且没有办法观察哪个操作将首先执行(除了unsafePerformIOIO的实施。 的执行顺序与结果无关

&&有一个9值的真值表,包括一个或两个参数都是undefined的情况,它确切地定义了操作:

a           b           a && b
True        True        True
True        False       False
True        undefined   undefined
False       True        False
False       False       False
False       undefined   False
undefined   True        undefined
undefined   False       undefined
undefined   undefined   undefined

只要实现遵循该表,就可以按任何顺序执行操作。

(如果您研究该表,您会注意到顺序实现无法遵循它,除非它首先执行a,然后b iff { {1}}是真的。但是Haskell实现不需要是顺序的!一个实现总是允许随时执行a;你唯一的保证是,根据在表中,执行b的结果只会在b为True时影响您的程序。)

(注意'懒惰'是使用如上所述的真值表编写函数的唯一方法;在像C或ML这样的语言中,所有五行都带有{{任何一个参数中的1}}都会强制a作为结果,在Haskell中(在C中,因为undefined内置于C语言中)其中一行可以undefined结果是1}}。)

答案 3 :(得分:-1)

我相信它的工作方式与你期望的一样;如果LHS评估为True,则评估RHS。但是,假设RHS没有副作用,你怎么知道(或关心)?

编辑:我猜RHS可能是undefined,然后你会关心......