【问题标题】:Evaluation (or none at all) of `_` Function Argument?`_`函数参数的评估(或根本不评估)?
【发布时间】:2015-12-01 13:19:31
【问题描述】:

给定数据类型,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 总是抛出它的单个参数,这是否意味着它的参数永远不会被评估,甚至是弱头范式?

【问题讨论】:

    标签: haskell lazy-evaluation


    【解决方案1】:

    不,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"
    

    【讨论】:

    • 由于nature of imprecise exceptions,看到f undefined 抛出与undefined 不同的错误不是充分证明f 是懒惰的。即使使用f x = x `seq` error "bad",编译器也可以抛出“坏”异常,而不是你从x 得到的异常——在紧要关头,你周围的任何旧异常都可以。
    • 谢谢,我已将其更改为只返回字符串“bad”。
    【解决方案2】:

    正如您所说,函数“f”从不评估其参数。这与参数是否为“Show”的实例无关。

    你也可以说

    Prelude> let f2 _ = "Some value"
    
    Prelude> f2 (Foo 5)
    "Some value"
    

    但真正的重点是,即使 f2 的参数未定义,它也不会被计算,因此不会抛出异常

    Prelude> f2 undefined
    "Some value"
    

    【讨论】:

      【解决方案3】:
      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!
      

      【讨论】:

        猜你喜欢
        • 2014-09-14
        • 2013-08-31
        • 1970-01-01
        • 2018-08-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-05
        相关资源
        最近更新 更多