Haskell:集合上的递归函数 [英] Haskell: Recursive Function on Sets

查看:123
本文介绍了Haskell:集合上的递归函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Haskell的新手,我试图编写一个基本的递归函数来生成一个集合的分区。我参考了这个wiki页面( https://en.wikipedia.org/wiki/Partition_of_a_set )为我定义的分区。

I am new to Haskell and I am trying to write a (somewhat) basic recursive function that generates the partitions of a set. I am referencing this wiki page (https://en.wikipedia.org/wiki/Partition_of_a_set) for my definition of set partitions.

我目前有一个函数可以产生大部分分区,但不是全部分区:

I currently have a function that produces most, but not all, of the partitions:

separate :: [a] -> [[[a]]]
separate [] = [[]]
separate (b:bs) = [[b]:s | s <- separate bs] ++ [(b:qs):qss | (qs:qss) <- separate bs]

>separate [1,2,3]
[[[1],[2],[3]],[[1],[2,3]],[[1,2],[3]],[[1,2,3]]]

您可以看到它缺少 [[1,3],[2]] 变体。

As you can see it is missing the [[1,3],[2]] variant.

我想知道这个函数是否可以很容易地修改来适应我的需求,或者是否需要创建一个全新的函数。感谢。

I was wondering if this function could be easily modified to accommodate my requirements, or if a whole new function would need to be created. Thanks.

推荐答案

问题在于使用 [(b:qs):qss | (qs:qss)< - separate bs] ,您只需将 b 添加到每个 bs 分区。您希望将它预先添加到每个子集中。

The problem is that with [(b:qs):qss | (qs:qss) <- separate bs], you only prepend b to the first subset of each of the bs partitions. You want to prepend it to every subset.

separate (b:bs) = [[b]:s | s <- separate bs]
               ++ (singleModifies (b:) =<< separate bs)

-- | All possibilities of applying a function to exactly one element in the list.
singleModifies :: (a->a) -> [a] -> [[a]]
singleModifies _ [] = []
singleModifies f (x:xs) = (f x:xs) : map (x:) (singleModifies f xs) 

如果您不明白 = << 操作符会:它变平列表的嵌套。 单独的bs 已经生成了一个分区列表;对于其中的每一个,我们从 singleModifies 获得另一个列表,但最终我们对哪个列表来自哪里并不感兴趣,所以我们只是 join (aka concat )。另一种写作方式是单独购买(b:bs)= [[b]:s | b

In case you don't understand what the =<< operator does: it “flattens” the nesting of lists. separate bs already generates a list of partitions; for each of these we get another list from singleModifies, but in the end we're not interested in which list came from where, so we just join (aka concat) them together. Another way for writing this would be

separate (b:bs) = [[b]:s | s <- separate bs]
               ++ concat [singleModifies (b:) bp | bp <- separate bs]

这篇关于Haskell:集合上的递归函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆