2012-06-24 48 views
1

是更好地做:在Haskell使用multine模式縮短函數定義

charToAction 'q' = Just $ WalkRight False 
charToAction 'd' = Just $ WalkRight True 
charToAction 'z' = Just Jump 
charToAction _ = Nothing 

charToAction x = case x of 
    'q' -> Just $ WalkRight False 
    'd' -> Just $ WalkRight True 
    'z' -> Just Jump 
    _ -> Nothing 

+0

你最喜歡哪一個?這兩種解決方案都沒有性能差異。就語法而言,隨你喜歡的人一起去吧。 –

+0

如果,案件,警衛,模式匹配,我被這些撕裂了! – L01man

+0

'if'和警衛不是很好的選擇,但你所問的兩個確實是等價的 - 事實上,GHC會在第一個彙編中的case中聲明一個函數的不同模式無論如何。 – leftaroundabout

回答

8

絕對沒有任何功能差異。這是個人喜好的問題。

+0

當你有多個關於備份和重試的意願時,你會發現有一些不同之處,但是你可以隨時脫離case case語句,因爲這是ghc核心發生的事情。 ;) –

2

沒有性能差異,因爲第一個定義脫到第二個。你是正確的選擇一個案例+模式匹配解決方案與守衛和平等測試,一些優秀的一般評論在這裏:http://existentialtype.wordpress.com/2011/03/15/boolean-blindness/(他的例子是ML,但立即轉化爲哈斯克爾)。

請注意,您在第二個定義中濫用otherwise;你應該只寫_ -> Nothing這不是你正在使用的警衛otherwise,你也可以寫fmap -> Nothing,也會發生同樣的情況。

+0

感謝您的文章!這是事實,布爾是非常低級的,因此應儘可能避免。 – L01man

1

正如其他人提到的,在生成的代碼沒有區別,因爲前者的做法desugars後一種方法,不過,我可以指出一些其他方面的考慮,可以幫助你選擇一個或另一個使用方法:

  1. 在某些情況下,前一種方法看起來更漂亮(雖然我個人認爲一旦有很多情況,它會讓人分心)
  2. 前一種方法使得重構名稱稍微困難一些。使用case語句,該函數的名稱只出現一次。
  3. Case語句可以在代碼中的任何地方使用,並且可以匿名使用。前一種方法需要使用letwhere塊來定義函數內的模式匹配函數。

但是,在任何情況下都不能將一個轉換成另一個。這完全是編碼風格的問題。