如何使用地图而不是列表理解 (Haskell)

How to use map instead of list comprehension (Haskell)

我编写了这段代码,它替换了满足谓词的列表中的所有元素:

gRep :: (t -> Bool) -> t -> [t] -> [t]
gRep pred x ys = [if pred y then x else y | y <- ys]

所以 f.eks 我得到这些输出:

ghci> gRep (<'g') 'z' "abcdefghijklmnopqrstuvwxyz"
"zzzzzzghijklmnopqrstuvwxyz"
ghci> gRep (<3) 0 [1,2,3,4,5,6,7,8,9]
[0,0,3,4,5,6,7,8,9]

如何改用 map 编写此函数?

我试着这样写:

gRepMap :: (t -> Bool) -> t -> [t] -> [t]
gRepMap pred x ys = map (\zs -> if (pred y) then x else y | y <- ys) ys

但是由于 | y <- ys 我得到一个解析器错误。我知道这可能是重复的,但我找不到处理此特定转换的问题。

lambda 表达式 \zs -> … 中的变量是 zs 这个变量将使用列表中的元素,因为 lambda 表达式是用列表中的每个元素调用的,因此你因此执行映射:

gRepMap :: (t -> Bool) -> t -> [t] -> [t]
gRepMap pred x ys = map (<strong>\zs -> if pred zs then x else zs</strong>) ys

通常在 Haskell 中,变量名称以 s 结尾,表示项目的 集合 (尤其是在使用列表时)。这里 zs 是该列表的一个元素,因此将变量命名为 yz 而不是 zs 更有意义:

gRepMap :: (t -> Bool) -> t -> [t] -> [t]
gRepMap pred x ys = map (\<strong>y</strong> -> if pred <strong>y</strong> then x else <strong>y</strong>) ys
gRep    pred x ys = [           if (pred y) then x else y | y <- ys]
--                                                         ^^^ ------>>>--.
gRepMap pred x ys = map (\ y -> if (pred y) then x else y )      ys   --  |
                          ^^^ <----------<<<--------------<<<-------------*

这就是 any 表达式在 list comprehension, according to the Haskell Reportoutput 部分的工作方式,它给出了等效的翻译,

 [ exp |     y <-        ys ]
===
 concatMap (\y -> [exp]) ys
===
 map       (\y ->  exp ) ys

Report 给出了一个更通用的翻译,在 irrefutable pattern 的情况下等同于上面的翻译,例如 y 在这里。

| y <- ys 位属于列表理解语法,你不应该在那里复制它。相反,y 成为 lambda 参数,ys 是被映射的列表。