簡體   English   中英

Haskell最好的風格是什么

[英]What's the best style in Haskell

感謝Erik Meijer的演講,也取得了重大進展。 好手表,也許暗示。 Haskell允許使用幾種方法來編寫相同的函數。 就效率和可讀性而言,哪一個最好?

sqr' = \x -> x * x
sqr'' x = x * x
sqr''' = (^2)

在這兩個頂級定義之間:

sqr' = \x -> x * x
sqr'' x = x * x

第二個在Haskell程序中幾乎是普遍首選的。 搜索幾乎所有現實世界中的Haskell代碼塊,您會發現第二個示例很多,但第一個示例很少。 相反,“ lambda抽象”(即\\x -> ...語法)最常用於定義匿名函數,以將其作為參數傳遞給高階函數。

選擇第二種語法有兩個原因。 首先,從字面上看,它更加簡潔,從可讀性的角度來看,它包含更少的不同語法元素(即並置和=運算符,而不是並置=\\-> )。 它還很好地概括了使用多個模式定義函數的常見Haskell習慣用法:

factorial 0 = 1
factorial n | n > 0 = n * factorial (n-1)

要使用lambda語法執行此操作,您需要添加一個顯式的case構造,其中涉及一套語法元素。

之間:

sqr'' x = x * x
sqr''' = (^2)

或者-也許是更公平的比較:

sqr'''' x = x^2
sqr''' = (^2)

這更多是個人喜好問題。 許多Haskell程序員喜歡所謂的無語法的外觀,其中較大的函數是使用高階函數和/或沒有明確參數的組合函數鏈組成的,例如:

mostFrequentWord
   = head . maximumBy (comparing length) . group . sort . words

sqr'''類的定義更符合這種總體風格。

就這些形式之間的含義差異而言,實際上有點復雜。 如果您采用以下模塊,則出於晦澀的原因,它們與稱為“單態性限制”和“默認規則”的事情有關:

module Square where
sqr' = \x -> x * x
sqr'' x = x * x
sqr''' = (^2)

並用ghc -O編譯, sqr'sqr'''的定義是等效的-兩者都將專門用於Integer類型,並且將生成完全相同的代碼。 (使用GHC 8.0.2測試)。 相反, sqr''保持多態性並帶有簽名Num a => a -> a sqr'' Num a => a -> a ,這意味着它可以對任何數字類型進行操作。

如果添加頂級類型簽名(無論如何,都是好的做法!),如下所示:

module Square where
sqr', sqr'', sqr''' :: (Num a) => a -> a
sqr' = \x -> x * x
sqr'' x = x * x
sqr''' = (^2)

然后它們都生成完全相同的代碼。 您可以使用以下方法查看生成的“核心”(編譯器在編譯過程中創建的中間點,類似於Haskell的中間語言),從而自己驗證這一點:

ghc -O -ddump-simpl -dsuppress-all -fforce-recomp Square.hs

在生成的核心中,您將看到定義:

sqr' = \ @ a_aBC $dNum_aLW x_arx -> * $dNum_aLW x_arx x_arx

看起來很奇怪,但從根本上說,將適當的Num類型的*操作應用於參數x_arx x_arx 為兩個變體生成的代碼:

sqr'' = sqr'
sqr''' = sqr'

表明GHC認為它們和sqr'之間沒有區別,因此在語義或性能上也沒有區別。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM