list - 用 Foldl 剪掉任何内容

标签 list haskell functional-programming option-type

我有一个列表 [也许是一个],我想在其中使用使用 Foldl 的函数剪切 Nothing 元素 例如剪切 [Just 2, Just 10, Nothing, Just 5] -> [2,10,5]

I wrote:
cut :: [Maybe a] -> [a]
cut a = foldl (help) [] a
               where help (x:xs) Nothing = (x:xs)
                     help (x:xs) Just a = a:(x:xs)

我的错误在哪里?

最佳答案

通过编写 help (x:xs) Nothing = (x:xs) 您已经使用了模式 (x:xs) 这意味着您希望累加器是一个包含至少一个元素的列表。但情况并非总是如此,例如初始累加器 [] 是空列表。

我们可以简单地使用变量l,而不是模式:

cut :: [Maybe a] -> [a]
cut a = foldl help [] a
               where help <b>l</b> Nothing = <b>l</b>
                     help <b>l</b> <b>(</b>Just a<b>)</b> = a:<b>l</b>

请注意,您还需要为带参数的构造函数添加括号。

但这并不能解决整个模式,现在您将颠倒列表。这是因为 foldl 从左到右迭代列表,因此您在迭代列表时会在前面添加值。我们可以使用 foldr 来代替。但现在该函数的类型不再起作用,因为 foldr 中的 help 函数将累加器作为第二个参数。所以我们可以翻转参数:

cut :: [Maybe a] -> [a]
cut a = fold<b>r</b> help [] a
               where help <b>Nothing l</b> = <b>l</b>
                     help <b>(Just a) l</b> = a:<b>l</b>

现在可以了。不过,我们可以稍微清理一下代码。例如,在 cut 函数上使用 eta 缩减:我们可以删除函数头部和主体中的 a:

cut :: [Maybe a] -> [a]
cut = foldr help []
               where help Nothing l = l
                     help (Just a) l = a:l

并且由于可以删除 help 中的第二个参数并将正文转换为函数:

cut :: [Maybe a] -> [a]
cut = foldr help []
               where help Nothing = <b>id</b>
                     help (Just a) = <b>(a:)</b>

我们还可以使用另一种变形:foldr是列表的变形,而maybeMaybe的变形,所以我们可以写一个:

maybe <value-in-case-of-nothing> <function-just-value> <Maybe value>

因此我们可以将帮助重写为:

<b>import Data.Maybe(maybe)</b>

cut :: [Maybe a] -> [a]
cut = foldr help []
               where help = <b>maybe id (:)</b>

或者只是将其作为 foldr 的参数注入(inject):

import Data.Maybe(maybe)

cut :: [Maybe a] -> [a]
cut = foldr <b>(maybe id (:))</b> []

所以现在我们在catamporhism内使用catamporhism,所以catamorphception

关于list - 用 Foldl 剪掉任何内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47329843/

相关文章:

unit-testing - 在 HUnit 中选择性运行测试

javascript - Rethinkdb 将对象数组转换为单个对象

scala - 什么时候命令式风格更合适?

facebook - 在 haskell 中编写 facebook 应用程序的最佳方法是什么?

Guards 中的 Haskell 类型解构

python - 在 python 中绘制二进制数据

python - 如何在一行中从数组中获取值(Python 3)

functional-programming - 函数式编程 : Best Platform/Environment

list - 打印 Erlang 列表中的每个元素

java - 在列表迭代期间从 java.util.List 中删除元素时引发 ConcurrentModificationException?