2014-03-01 30 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