两种映射实现之间有什么区别,一种使用列表理解,另一种使用递归?

use*_*222 2 haskell functional-programming

我刚刚接触 Haskell,我一直在浏览网站上的《Learn you a Haskell》一书。现在我正在学习高阶函数章节。

作者谈到了实现自定义地图功能。我想用我所掌握的一点点知识来实现​​它,然后与作者进行比较。我使用了列表理解,而作者使用了递归。与标准库相同

-- me
map1 :: (t -> a) -> [t] -> [a]
map1 f xs = [f x | x<-xs]

-- author
map2 :: (t -> a) -> [t] -> [a]
map2 _ [] = []
map2 f (x:xs) = f x : map2 f xs
Run Code Online (Sandbox Code Playgroud)

为什么选择递归高于列表理解?它的性能更好吗?

只是想知道为什么事情会变成这样?

Dan*_*ner 9

这里没有什么特别深刻的事情。在任何合理的 Haskell 实现中,这两个实现应该本质上相同。

不过,使用递归和模式匹配的版本确实有一些优点。

  1. 它使用语言的“更原始”部分。事实上,Haskell 实现在内部将列表推导式转换为对map其他类似函数的调用或直接递归定义是非常合理的。
  2. 它更具有普遍性。标准 Haskell 2010 中没有针对其他数据类型(例如树、数组、集合、字典等)的类似列表理解的语法糖。但是模式匹配可用于各种常见类型,并且递归在所有情况下都很有用。地方。
  3. 这是很好的教学法。对于一些来自命令式背景的人来说,递归尤其可能不熟悉。此外,使用递归的实现将其函数参数传递给另一个函数调用,从而充分利用了 Haskell 支持函数作为第一类对象的事实。有些语言并不完全支持该功能,因此查看、使用和使用该功能可能会对某些人造成障碍。

  • “对于树、数组、集合、字典等其他数据类型,没有类似列表理解的语法糖。” [_实际上_,](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/monad_compressives.html) (2认同)