【问题标题】:In Haskell, what could `this@(Sentence string _) = do` mean?在 Haskell 中,`this@(Sentence string _) = do` 是什么意思?
【发布时间】:2013-03-07 18:29:52
【问题描述】:

这是我被分配调试的 Haskell 程序的一部分:

process :: Sentence -> IO ()
process this@(Sentence string _) = do
  render string
  render "==>"
  render $ translate this

render = putStrLn

data Sentence = Sentence String Task

translate :: Sentence -> String     ; Incomplete Definition
translate (Sentence string task)
  | ...

  | ...

  | ...

  | ...

这个程序中唯一我不理解或不认识的部分是process this@(Sentence string _) = do这一行 我以前从未见过this@,我也不太确定(Sentence string _) 中的下划线是什么意思。

【问题讨论】:

    标签: haskell


    【解决方案1】:

    this@ 是“as-pattern”的示例,而_ 是通配符模式的示例。当我们不关心模式中该点的值时,使用通配符模式,因此模式中的_ 将匹配任何内容,并且它不绑定任何本地名称/变量。

    另一方面,当我们想绑定一个额外的本地名称/变量同时匹配它时,我们使用 as 模式。你可以考虑一下

    process this@(Sentence string _) = ...
    

    大致相当于

    process this = let (Sentence string _) = this
                   in ...
    

    它将@ 符号左侧给出的额外名称绑定到它匹配的任何值。 at 模式本身匹配所有内容,但 @ 符号右侧的内部模式也匹配它匹配的任何内容 - 并且该模式很可能不匹配所有内容,在这种情况下它仅匹配 Sentence构造函数。

    正因为如此,如果 let 绑定中的模式匹配失败,at 模式版本和带有 let 绑定的版本会有不同的行为,所以当我们为一个函数定义多个 case 时,通常首选 at 模式,例如它允许内部模式也影响调用函数的哪种情况。例如

    safeHead xs = let (x:_) = xs in Just x
    safeHead [] = Nothing
    

    []调用会失败,因为xs对第一个参数的模式匹配成功,所以调用函数的第一个case,然后xs不能匹配(x:_)。但是,如果我们用 as 模式写这个:

    safeHead xs@(x:_) = Just x
    safeHead [] = Nothing
    

    使用[] 调用会正常工作,因为在我们决定使用函数的第一种情况之前,也会检查内部模式,因此虽然xs 匹配[](x:_) 也匹配[],失败了,然后调用第二种情况。我意识到这是一个非常愚蠢的例子,尤其是我们第二次不使用 xs 时,但我希望它能说明不同之处。

    【讨论】:

    • 你是说我需要在 this@ 语句之后添加一个条件来捕获不匹配的输入吗?
    • 请注意,这在传统上被称为“as-pattern”,但有些人称之为“at-pattern”的想法并不令人惊讶。
    • @ThomasM.DuBuisson 你说得对,我真的应该知道我已经盯着 AST 节点看多少次了:P
    • @Imray 不是真的不 - 我的意思是 as 模式允许您将名称绑定到一个值,并且还可以针对该值进行模式匹配。就绑定的名称而言,这类似于仅对名称进行模式匹配,然后让或大小写匹配模式。但是,如果任何部分(特别是 @ 右侧的部分不匹配),整个 as 模式 this@(Sentence string _) 将无法匹配(并且使用不同的大小写)。这和绑定名称this然后分别匹配(Sentence string _)是不一样的。
    【解决方案2】:

    @ 定义了一个 as pattern,它允许您命名要匹配的事物。在这种情况下,this 是您匹配的 Sentence 值的名称。

    【讨论】:

      【解决方案3】:

      Sentence 是一个构造函数,它接受一个String 和一个Task,在模式this@(Sentence string _) 中,this 是一个命名整个句子的as patternstring 命名句子的@987654328 @,下划线位于 Task 的其他名称处,本质上是说 Task 应该在那里被忽略。

      【讨论】:

      • 阅读整篇文章后,对于 @ 符号的含义只有愚蠢且非详尽的描述。您能否在答案中添加一个简单但更有说服力的示例?
      猜你喜欢
      • 2020-06-14
      • 1970-01-01
      • 1970-01-01
      • 2011-06-20
      • 2015-09-14
      • 2016-09-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多