您最有可能写下以下哪项?
r = zip xs $ map sqrt xs
或
r = [(x, sqrt x) | x <- xs]
互联网上的示例代码似乎表明前者更为丰富且是首选方式。
答案 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.Monad
和Control.Monad.Instances
后)
map (ap (,) sqrt) xs
另一个尚未提及的替代方案是
zipWith (,) xs (map sqrt xs)
答案 5 :(得分:6)
我很少使用列表推导,但两者都很花哨。只需使用使您的代码更易于阅读的那个。
答案 6 :(得分:6)
我更像是一个“老派”Haskellier,所以我使用zip `ap` map sqrt
然后重构它以使用<*>
代替ap
。
申请人是新的Monad。 (在“酷哈斯克尔儿童最近使用的是什么?”的意义上)。