haskell 很漂亮。这是事实。它简洁、快速等。你们中的许多人都会承认用它写作是一种极大的乐趣。另一方面,我认为当人们尝试编写过于复杂的代码时,它的简洁性可能是一个缺点。例如,我最近打开我 friend 的项目,发现了这样的内容:
stationDepartures id sc=map (\(s1,list)->(stationName $ (stationMap $ system sc) Map.! s1,list)) ( Map.toList (Map.fromListWith (++) (map (\((s1,s2),(d,start,dur))->(s2,[start])) (Map.toList (Map.filterWithKey (\(s1,s2) _ ->s1==id) (Map.unions (List.map times (Map.elems $ schedule sc))))))))
这句台词对我来说完全无法读懂。这当然是一个相当极端的例子,但它帮助我意识到也许我的 Haskell 代码对其他人来说可能难以阅读。我开始想知道在 Haskell 中创建漂亮代码的原则是什么。我发现例如有些人认为 lambda 函数是多余的,因为它们使代码的可读性较差。你对此有何看法? Haskell 代码应该满足什么要求才能被认为是“美丽的”?
最佳答案
我假设您问:“我怎样才能以更具可读性的方式写出这段单行文字?”否则这个问题就有点太主观了。
单行代码在任何语言中都是有问题的,尽管 Haskell 由于大量的二元运算符(具有优先级规则)、高阶函数(很难命名)和(惊呼!)高阶函数,问题尤其严重函数是二元运算符。然而,我们首先可以注意到,单行代码中的大多数括号都可以被消除,并且我们可以证明该表达式是一系列组合在一起的函数。每个函数都可以写在单独的行上,并由 .
组成,最后的 $
将整个函数应用于参数。
stationDepartures id sc =
map (\(s1,list) -> (stationName $ (stationMap $ system sc) Map.! s1,
list)) .
Map.toList .
Map.fromListWith (++) .
map (\((s1,s2),(d,start,dur)) -> (s2,[start])) .
Map.toList .
Map.filterWithKey (\(s1,s2) _ -> s1 == id) .
Map.unions .
List.map times .
Map.elems $ schedule sc
对我来说,这是相当可读的,因为我识别其中的模式,并且我可以从下到上跟踪数据流。 (注意:这就是为什么所有 Map
函数都将 Map
作为最后一个参数而不是第一个参数。当您使用设计你的 Haskell API!)
例如,Map.toList。 Map.fromListWith f
模式非常常见,只是很难在一行中看到它(至少在我看来)。该代码实际上并不是那么复杂,只是通过手术删除了换行符。
但是,可读性是主观的。
您将形成一种易于阅读的风格。随着您对语言的了解越来越多,风格将会演变,您对“美丽代码”的感觉也会演变。就让它发生吧,尽量不要陷入太多的重写中,这样你就不再有乐趣了。
关于haskell - 美丽而可怕的 haskell ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11128759/