2016-12-30 31 views
2

所以我試圖匹配這種模式。 MessageType是我創建的一個類型。該函數接受一個字符串,然後根據該字符串的第一個字符輸出一個MessageType。每當我編譯不過,我得到一個警告說法:模式匹配是不具有說服力的 - 我的「其他方面」在最後一名後衛中未能處理空列表?

Pattern match(es) are non-exhaustive 
    In an equation for ‘parseMessage’: Patterns not matched: [] 

這裏是我的代碼:

parseMessage :: String -> MessageType 
parseMessage (x:_) 
    | x == 'I'  = Info 
    | x == 'W'  = Warning 
    | otherwise  = Error 1 

它怎麼說,我的模式匹配並非詳盡無遺? otherwise後衛不會抓住其他什麼嗎?我不明白我的函數不能捕捉所有的字符串。

當我寫這樣的功能,我沒有得到警告。

parseMessage []  = error "Empty String" 
parseMessage (x:_) = if x == 'I' 
         then Info 
         else if x == 'W' 
         then Warning 
         else Error 1 

我重寫了我的函數,因爲我看到警告說「模式不匹配:[]」,所以我明確地處理它。但爲什麼在我的函數的第一個版本中,它說這個模式沒有被處理。 otherwise除了前兩名警衛之外怎麼也沒有抓到?

回答

12

逆天特定於函數的定義,一個模式的情況下,所以,當你寫:

parseMessage (x:_) 
    | x == 'I'  = Info 
    | x == 'W'  = Warning 
    | otherwise  = Error 1 

...您的衛兵甚至不會進行協商,如果你運行parseMessage ""(x:_)模式會失敗,所以它的所有守衛都會被忽略。這需要是爲了使x在警戒條件下受到約束。

爲了解決這個問題,你只需要添加處理空字符串的情況下:

parseMessage :: String -> MessageType 
parseMessage "" = Error 1 
parseMessage (x:_) 
    | x == 'I'  = Info 
    | x == 'W'  = Warning 
    | otherwise  = Error 1 

現在你已經處理所有可能的情況。

+1

我想擺脫'otherwise'條款,並在末尾添加'parseMessage _ =錯誤1'。 – dfeuer

+4

啊,我明白了。由於我設置了檢查列表的第一個元素的初始模式,空字符串不會被警衛抓住。 –

8

爲什麼不直接寫...

parseMessage ('I':_) = Info 
parseMessage ('W':_) = Warning 
parseMessage _  = Error 1 
相關問題