haskell - 硬件 : Unfolding a list in a specific way

标签 haskell functional-programming unfold

在 Haskell 编程中,Graham Hutton 定义了列表的展开,如下所示:

unfold :: (b -> Bool ) -> (b -> a) -> (b -> b) -> b -> [a]
unfold p h t x | p x = []
| otherwise = h x : unfold p h t (t x)

定义一个函数

• listUnfold :: (b -> Bool) -> (b -> a) -> (b -> b) -> b -> [a]

与上面的类似,但在其实现中使用unfoldr并且是非递归的。

我已经尝试解决上述问题有一段时间了,但我仍然可以设法做到这一点(在 Haskell 和一般函数式编程中相当新)。

我的尝试:

listUnfold :: (b -> Bool) -> (b -> a) -> (b -> b) -> b -> [a]
listUnfold f h t x 
    | f x == True   = []
    | otherwise     = h x : 
        listUnfoldr (\x -> if f x then Nothing else Just ((h x), (t x))) x

在英语中,如果 f x 为 true,则返回空列表。否则,使用 h x 作为头部,并附加展开器的结果作为尾部。 Unfoldr 接受一个列表 (x:xs) ,该列表应以 x 作为头部,以 xs 作为尾部进行递归。

p/s:我可能做得非常非常错误。

最佳答案

你已经快明白了!原始函数使用函数 p(表示“谓词”)来确定我们是否已完成展开,使用 h 应用于每个元素,使用 t code> (“转换”)将元素转换为列表其余部分的种子。

unfoldr 需要一个函数 f::b -> Maybe (a,b),如果我们完成则返回 Nothing展开,或 Just (x, y),其中 x 是要添加到列表中的元素,y 是其余元素的种子列表。

因此,unfoldr 中的 f 负责 ph 所有三个的功能>tNothing-or-Just 二分法扮演 bool 函数 p 的角色,元组的第二个元素扮演 t 的工作是为列表的其余部分提供种子。

这是我的解决方案(为了清楚起见,我已重命名了您问题中的变量):

listUnfold pred f trans seed =
    unfoldr (\x -> if pred x
                   then Nothing
                   else Just (f x, trans x)) seed

当然,当一个值出现在定义的右侧时,就像这里的seed一样,您可以利用Haskell的柯里化(Currying)语法,并将其完全丢弃:

listUnfold pred f trans = unfoldr (\x -> if pred x
                                         then Nothing
                                         else Just (f x, trans x))

正式而言,此转换称为 eta reduction .

关于haskell - 硬件 : Unfolding a list in a specific way,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15537100/

相关文章:

clojure - Clojure 有 "unfold"吗?

javascript - 函数式 JavaScript : good practice to avoid argument mutation?

functional-programming - 如何从数据类型中提取元组?

javascript - 聚合和转换对象数组

haskell - Haskell递归问题,微小的解析器。否定Expr和let表达式

algorithm - 我怎样才能展开重复: T(n)=2T((n+2)/3)

haskell - cofree comonad 的可展开实例

haskell - 将 GADT 与 DataKinds 用于函数中的类型级数据构造函数约束

haskell - 如何在 Haskell 中运行一系列操作(函数)?

haskell - 如何反序列化 JSON,其中相应的 Haskell 类型在运行时可作为值使用?