2014-03-01 64 views
13

當我使用Functors,Monads和其他Hakell構造時,如果我的代碼不僅僅是幾行,我更喜歡使用一些語法糖,比如do not notation。這使我更容易遵循代碼流程。在文體偏好之外,使用脫糖糖塊與加糖替代品相比有沒有真正的優勢?Haskell desugaring的優點?

回答

18

我認爲人們把這個問題視爲愚蠢是一種恥辱,尤其是因爲與此處表達的最強烈的意見相反,答案是,避免do-sugar可能會有好處。 Simon Marlow在他正在研究的talk about the Facebook Haxl project中給出了一個很好的例子。這是一個簡短的,毫無疑問的屠殺版本 - 絕對看他的幻燈片瞭解更多細節!

這裏的Facebook可能要運行一個查詢的例子:

numCommonFriends x y = do 
    fx <- friendsOf x 
    fy <- friendsOf y 
    return (length (intersect fx fy)) 

與糖,這是美麗的。不幸的是,這也是嚴重順序。事實證明,你可以設計一個單子,使得上述可能,但嚴重underperformant,以及以下非含糖應用型版本顯著更好的性能:

numCommonFriends x y = length <$> liftA2 intersect (friendsOf x) (friendsOf y) 

點這裏在於應用型實例都有同時運行friendsOf立即分支:靜態地清楚,第二次調用friendsOf不能依賴於第一個。這是monadic綁定無法重複的壯舉,因爲在bind的第二個參數中計算的動作可能取決於第一個參數中的計算結果。據我所知,設計一種允許進行這種優化的新型糖,目前是一個活躍的研究問題。

+4

好吧,我的有機磷農藥的問題解釋是在做標記,其脫糖比較等價的,就像'friendsOf x >> =(\ fx - > friendsOf y >> =(\ fy - > return(length(intersect fx fy))))'就我所知(或者可能更好使用'liftM2'的變體)。我必須承認,你的解釋給出了一個更有趣的觀點。我仍然不確定這是否意味着OP,但我們主要不是在這裏幫助人們,而是爲了記錄知識,這肯定是Haskell程序員應該注意的東西。 –

+0

是的,應用程序的優雅和清晰度(在大多數情況下)是我使用它的動機,因爲它與解析樹時最直接類似。 –

+0

我並沒有真正考慮過並行評估方面的問題。感謝這篇論文的指針。 –

5

嗯,沒有。糖的整個意義在於,它完全脫離了脫糖的版本,所以不存在任何非文體優勢。您可能會習慣使用desugared notation,以便在的樣式更清晰時遵循它,但由於代碼完全相同,因此您不會獲得任何性能優勢或任何其他優勢。

1

丹尼爾認爲,從性能角度來看,從可讀性的角度來看,amalloy提出反對解僱。

我認爲,有時候,脫糖的版本只是更具可讀性即比較

echo :: IO() 
echo = do 
    ln <- getLine 
    putStrLn ln 

echo :: IO() 
echo = putStrLn =<< getLine 
+0

這有一個缺點,即'putStrLn'出現在'getLine'之前,而前者稍後執行。爲了解決這個問題,說'getLine >> = putStrLn',這更可讀。 –

+0

@EarthEngine如果你正在考慮「首先運行,然後運行」,那麼這是真的。我正在讀它作爲'putStrLn $ getLine',其中'$ getLine'是我從getLine獲得的字符串 - 所以我更多地閱讀它「這是我要做的事情,這裏是輸入的地方從」。 – Cubic