gpt4 book ai didi

haskell - 内部爆炸模式是否总是强制 Haskell 中的外部构造函数?

转载 作者:行者123 更新时间:2023-12-04 04:14:38 25 4
gpt4 key购买 nike

在 Haskell 中,是否存在一种数据类型

{-# LANGUAGE BangPatterns #-}
import Control.DeepSeq

data D = D Int

实例
instance NFData D where
rnf (D !_) = ()

与具有另一个外部 ! 的实例可能具有不同的效果:
instance NFData D where
rnf !(D !_) = ()

我的研究:
  • https://downloads.haskell.org/~ghc/8.6.3/docs/html/users_guide/glasgow_exts.html#bang-patterns-informal只谈let绑定(bind)(如 this 答案),我认为它不适用于这样的函数模式匹配。
  • https://prime.haskell.org/wiki/BangPatterns#Thebasicidea

    A bang only really has an effect if it precedes a variable or wild-card pattern





    putting a bang before a pattern that forces evaluation anyway does nothing



    我认为
  • rnf (D _)无论如何已经强制评估
  • 因为它就像 rnf x = case x of D _ -> ...
  • 所以rnf !(D _)rnf (D _) 的效果相同
  • 因此通过替换rnf !(D !_)必须与 rnf (D !_) 具有相同的效果

  • 所以我认为不,这两个总是等价的,但无论如何我要求有一个 super 明确的答案来推荐人们。

    最佳答案

    确实这是正确的。我们可以使用 :sprint 查看评估的内容在 GHCi ,它向我们展示了已评估的 thunk。

    没有爆炸模式:

    λ data D = D Int
    λ d1 = D 1
    λ :sprint d1
    d1 = _
    λ f1 (D _) = 0
    λ f1 d1
    0
    λ :sprint d1
    d1 = <D> _ -- Only D evaluated

    带有内刘海图案:
    λ d2 = D 2
    λ :sprint d2
    d2 = _
    λ f2 (D !_) = 0
    λ f2 d2
    0
    λ :sprint d2
    d2 = <D> 2 -- Everything evaluated

    带有外刘海图案:
    λ d3 = D 3
    λ :sprint d3
    d3 = _
    λ f3 !(D _) = 0
    λ f3 d3
    0
    λ :sprint d3
    d3 = <D> _ -- Only D evaluated

    具有内刘海和外刘海图案:
    λ d4 = D 4
    λ :sprint d4
    d4 = _
    λ f4 !(D !_) = 0
    λ f4 d4
    0
    λ :sprint d4
    d4 = <D> 4 -- Everything evaluated

    从这里我们可以很容易地看到模式 !(D !_)(D !_)是等价的,而且 !(D ...) 形式的模式是多余的。

    关于haskell - 内部爆炸模式是否总是强制 Haskell 中的外部构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53841764/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com