2013-03-07 71 views
2

這是我被分配到調試一個Haskell程序的一部分:在Haskell中,this @(Sentence string _)= do`是什麼意思?

process :: Sentence -> IO() 
process [email protected](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) 
    | ... 

    | ... 

    | ... 

    | ... 

這個節目,我不理解或認識的唯一部分是之前,我從來沒有見過[email protected]process [email protected](Sentence string _) = do 我也不太確定(Sentence string _)中的下劃線是什麼意思。

回答

7

[email protected]是'as-pattern'的示例,而_是通配符模式的示例。當我們不關心模式中的那個值時,通配符模式被使用,因此模式中的_將與任何事物匹配,並且它不綁定任何本地名稱/變量。

另一方面,當我們想綁定一個額外的本地名稱/變量同時也與之匹配時,我們使用as模式。你可以認爲

process [email protected](Sentence string _) = ... 

大致相當於

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

它結合在@號左邊到任何的是匹配值給出額外的名字。 at模式本身可以匹配所有內容,但@符號右側的內部模式也會與匹配的內容相匹配 - 並且該模式可能不匹配所有內容,在這種情況下,它只匹配Sentence構造函數。

因此,如果let綁定中的模式匹配可能會失敗,那麼at模式版本和帶有let綁定的版本會有不同的行爲,所以at模式通常是首選的,當我們爲函數定義多個case時,因爲它允許內部模式也影響函數的哪種情況被調用。例如

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

當與[]調用時,第一個參數成功,因此函數的第一種情況下被調用,然後xs不能針對(x:_)匹配將失敗作爲xs模式匹配。但是,如果我們用寫這爲模式:

safeHead [email protected](x:_) = Just x 
safeHead [] = Nothing 

[]調用將正常工作,因爲內模式還檢查之前,我們決定使用功能的第一種情況,以及對因此雖然xs比賽[](x:_)也與[]匹配,這會失敗,因此第二種情況會被調用。我意識到這是一個相當愚蠢的例子,特別是因爲我們第二次不使用xs,但我希望它能說明它們的不同之處。

+0

你是說我需要在這個@語句之後添加一個條件來捕獲不匹配的輸入嗎? – CodyBugstein 2013-03-07 20:00:43

+2

請注意,這通常被稱爲「as-pattern」,但有些人稱之爲「at-pattern」的想法並不令人驚訝。 – 2013-03-07 20:50:04

+0

@ ThomasM.DuBuisson你說的沒錯,我真的應該知道我有多少次盯着AST節點的模式:P – DarkOtter 2013-03-07 22:42:40

4

@定義了一個as pattern它允許您命名匹配的東西。在這種情況下,this是您匹配的Sentence值的名稱。

4

Sentence是一個構造函數一個StringTask,在模式[email protected](Sentence string _)thisas pattern名稱整個句子,string名句子的String和下劃線去哪裏了Task否則將被命名,本質上說Task應該忽略那裏。

+0

非常有幫助的鏈接!謝謝 – CodyBugstein 2013-03-07 20:01:42

+0

閱讀完整篇文章後,對@符號的含義只有愚蠢的和非詳盡的描述。你能給你的答案增加一個簡單但更確切的例子嗎? – CodyBugstein 2013-03-07 20:24:31