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

r = zip xs $ map sqrt xs

或者

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

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

有帮助吗?

解决方案

我可能会写

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

如果您希望免费,以上等同于(导入后 Control.MonadControl.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孩子使用什么?”的意义上

我很少使用列表综合,但两者都是花花公子。只需使用使您的代码易于阅读的一个即可。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top