Haskell地图/邮编Vs.列表理解

时间:2010-07-04 18:09:23

标签: haskell zip list-comprehension pointfree combinators

您最有可能写下以下哪项?

r = zip xs $ map sqrt xs

r = [(x, sqrt x) | x <- xs]

互联网上的示例代码似乎表明前者更为丰富且是首选方式。

7 个答案:

答案 0 :(得分:24)

在#haskell上花费太多时间的人可能会把它写成

r = map (id &&& sqrt) xs

(&&&)Control.Arrow中定义的有趣组合子。它的实际类型签名很复杂,因为它推广到Arrow的所有实例。但它通常与(->)的{​​{1}}实例一起使用,从而产生此类签名:

Arrow

答案 1 :(得分:15)

虽然我不经常使用它们,但在这种情况下,我认为我更喜欢列表理解版本,因为它对我来说似乎更清晰。

如果你有点自由风格,你可能也喜欢这个:

f = zip `ap` map sqrt

ap存在于Control.Monad中,在这种情况下,它可以被认为是S组合子,它在SKI calculus中概括了应用程序:

ap f g x == f x (g x)
ap const const == id

正如Conal指出的那样,这也可以从Monad推广到Applicative(导入Control.Applicative):

f = zip <*> map sqrt

答案 2 :(得分:11)

我可能会写map / zip,然后希望我写完了列表理解。

答案 3 :(得分:9)

对于某些类型的问题(特别是Project Euler),这个特殊情况经常出现,我写了下面的小帮手:

with :: (a -> b) -> a -> (a,b)
with f a = (a, f a)

这样可以编写您的示例:

r = map (with sqrt) xs

答案 4 :(得分:9)

我可能会写

map (\x -> (x, sqrt x)) xs

如果您更喜欢无点,则上述内容相当于(导入Control.MonadControl.Monad.Instances后)

map (ap (,) sqrt) xs

另一个尚未提及的替代方案是

zipWith (,) xs (map sqrt xs)

答案 5 :(得分:6)

我很少使用列表推导,但两者都很花哨。只需使用使您的代码更易于阅读的那个。

答案 6 :(得分:6)

我更像是一个“老派”Haskellier,所以我使用zip `ap` map sqrt然后重构它以使用<*>代替ap

申请人是新的Monad。 (在“酷哈斯克尔儿童最近使用的是什么?”的意义上)。