在Haskell中,这个@(Sentence string _)= do`是什么意思?

时间:2013-03-07 18:29:53

标签: haskell

这是我分配给调试的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 _)中的下划线是什么意思。

3 个答案:

答案 0 :(得分:7)

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

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

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

大致相当于

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

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

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

Sentence

使用safeHead xs = let (x:_) = xs in Just x safeHead [] = Nothing 调用时会失败,因为第一个参数的[]模式匹配成功,因此调用该函数的第一个案例,然后xs无法匹配反对xs。但是,如果我们用as模式写这个:

(x:_)

使用safeHead xs@(x:_) = Just x safeHead [] = Nothing 调用可以正常工作,因为在我们决定使用函数的第一个案例之前也会检查内部模式,因此虽然[]xs匹配,但{ {1}}也与[]匹配,失败,因此第二种情况被调用。我意识到这是一个非常愚蠢的例子,特别是因为我们第二次不使用xs,但我希望它能说明差异。

答案 1 :(得分:4)

@定义as pattern,允许您为匹配的内容命名。在这种情况下,this是您要匹配的Sentence值的名称。

答案 2 :(得分:4)

Sentence是一个带StringTask的构造函数,在模式this@(Sentence string _)中,thisas pattern的名字整句,string命名为句子String,下划线指的是Task以其他方式命名的地方,基本上说Task应该在那里被忽略。