Haskell Map/zip vs。列表理解
-
02-10-2019 - |
题
您最有可能编写以下哪项?
r = zip xs $ map sqrt xs
或者
r = [(x, sqrt x) | x <- xs]
互联网上的示例代码似乎表明前者更丰富,并且是首选的方式。
解决方案
我可能会写
map (\x -> (x, sqrt x)) xs
如果您希望免费,以上等同于(导入后 Control.Monad
和 Control.Monad.Instances
)
map (ap (,) sqrt) xs
尚未提到的另一个替代方案是
zipWith (,) xs (map sqrt xs)
其他提示
在#Haskell花费太多时间的人可能会将其写为
r = map (id &&& sqrt) xs
(&&&)
是定义的有趣组合器 Control.Arrow
. 。它的实际类型签名很复杂,因为它已概括为所有箭头实例。但是它经常与 (->)
实例 Arrow
, ,导致这种类型的签名:
(&&&) :: (a -> b) -> (a -> c) -> a -> (b, c)
尽管我倾向于不经常使用它们,但在这种情况下,我认为我更喜欢列表理解版本,因为对我来说似乎更干净。
如果您是自由风格的样式,那么您也可能会喜欢:
f = zip `ap` map sqrt
AP生活在控制中,Monad,在这种情况下,可以将其视为S组合者,它概括了在 滑雪微积分:
ap f g x == f x (g x)
ap const const == id
正如Conal所指出的那样,这也可以从单月到适用性概括(进口控制。应用):
f = zip <*> map sqrt
我可能会写 map
/zip
然后后来希望我写了列表的理解。
对于某些类型的问题(Euler项目 特别是),这种特殊情况经常出现,以至于我写了以下小帮手:
with :: (a -> b) -> a -> (a,b)
with f a = (a, f a)
这允许您写下您的示例:
r = map (with sqrt) xs
我更像是一个“老派”哈斯克利尔,所以我会用 zip `ap` map sqrt
然后重构它使用 <*>
代替 ap
.
适用的是新的单子。 (从“如今酷的Haskell孩子使用什么?”的意义上
我很少使用列表综合,但两者都是花花公子。只需使用使您的代码易于阅读的一个即可。
不隶属于 StackOverflow