qre*_*est 19 zip haskell list-comprehension combinators pointfree
您最有可能写下以下哪项?
r = zip xs $ map sqrt xs
Run Code Online (Sandbox Code Playgroud)
要么
r = [(x, sqrt x) | x <- xs]
Run Code Online (Sandbox Code Playgroud)
互联网上的示例代码似乎表明前者更为丰富且是首选方式.
Car*_*arl 25
在#haskell花费太多时间的人可能会把它写成
r = map (id &&& sqrt) xs
Run Code Online (Sandbox Code Playgroud)
(&&&)
是一个有趣的组合器Control.Arrow
.它的实际类型签名很复杂,因为它推广到Arrow的所有实例.但它经常与(->)
实例一起使用Arrow
,这导致了这种类型的签名:
(&&&) :: (a -> b) -> (a -> c) -> a -> (b, c)
Run Code Online (Sandbox Code Playgroud)
dan*_*lei 16
虽然我不经常使用它们,但在这种情况下,我认为我更喜欢列表理解版本,因为它对我来说似乎更清晰.
如果你是点自由风格,你也可能喜欢这个:
f = zip `ap` map sqrt
Run Code Online (Sandbox Code Playgroud)
ap存在于Control.Monad中,在这种情况下,它可以被认为是S组合子,它在SKI演算中推广应用:
ap f g x == f x (g x)
ap const const == id
Run Code Online (Sandbox Code Playgroud)
正如Conal指出的那样,这也可以从Monad推广到Applicative(导入Control.Applicative):
f = zip <*> map sqrt
Run Code Online (Sandbox Code Playgroud)
Mtn*_*ark 10
对于某些类型的问题(特别是Project Euler),这个特殊情况经常出现,我写了下面的小助手:
with :: (a -> b) -> a -> (a,b)
with f a = (a, f a)
Run Code Online (Sandbox Code Playgroud)
这允许您编写示例:
r = map (with sqrt) xs
Run Code Online (Sandbox Code Playgroud)
Gre*_*con 10
我可能会写
map (\x -> (x, sqrt x)) xs
Run Code Online (Sandbox Code Playgroud)
如果你喜欢自由点,上面是等同于(在已进口Control.Monad
和Control.Monad.Instances
)
map (ap (,) sqrt) xs
Run Code Online (Sandbox Code Playgroud)
另一个尚未提及的替代方案是
zipWith (,) xs (map sqrt xs)
Run Code Online (Sandbox Code Playgroud)
我更像是一个"老派"Haskellier,所以我会使用zip `ap` map sqrt
它,然后重构它来<*>
代替ap
.
适用的是新的Monad.(在"酷Haskell孩子们最近使用的是什么?"的意义上)