【问题标题】:How to use map instead of list comprehension (Haskell)如何使用地图而不是列表理解(Haskell)
【发布时间】:2021-12-04 21:32:14
【问题描述】:

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

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 &lt;- ys ,我收到了解析器错误。我知道这可能是重复的,但我找不到处理此特定转换的问题。

【问题讨论】:

    标签: list haskell list-comprehension


    【解决方案1】:
    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   --  |
                              ^^^ <----------<<<--------------<<<-------------*
    

    根据Haskell Reportlist comprehensionoutput 部分中的 any 表达式就是这样工作的,它给出了等效的翻译,

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

    报告给出了一个更一般的翻译,相当于上面在无可辩驳的模式的情况下,就像y在这里。

    | y &lt;- ys 位属于列表解析语法,您不应该将它复制到那里。相反,y 成为 lambda 参数,ys 是被映射的列表。

    【讨论】:

      【解决方案2】:

      lamba 表达式中的变量\zs -&gt; …zs 这个变量将使用列表中的元素,因为使用列表中的每个元素调用 lambda 表达式,因此您可以使用以下方式执行映射:

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-12-11
        • 2022-01-08
        • 1970-01-01
        • 2023-03-08
        • 1970-01-01
        相关资源
        最近更新 更多