什么叫分割列表的函数?

时间:2011-03-25 21:57:50

标签: haskell f# functional-programming sml split

我想编写一个函数,根据满足给定属性p的项目将列表拆分为子列表。我的问题是如何调用该函数。我将在Haskell中给出示例,但同样的问题会出现在F#或ML中。

split :: (a -> Bool) -> [a] -> [[a]]  --- split lists into list of sublists

连接的子列表是原始列表:

concat (split p xss) == xs

每个子列表都满足initial_p_only p属性,也就是说(A)子列表以满足p的元素开头 - 因此不是空的,并且(B)没有其他元素满足{{ 1}}:

p

所以准确一点,

initial_p_only :: (a -> Bool) -> [a] -> Bool
initial_p_only p [] = False
initial_p_only p (x:xs) = p x && all (not . p) xs

如果原始列表中的第一个元素不满足all (initial_p_only p) (split p xss) ,则拆分失败。

此函数需要被称为p以外的其他函数。 我该怎么称呼?

2 个答案:

答案 0 :(得分:12)

我相信您所描述的功能来自list-grouping包中的breakBefore

Data.List.Groupinghttp://hackage.haskell.org/packages/archive/list-grouping/0.1.1/doc/html/Data-List-Grouping.html

ghci> breakBefore even [3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3,2,3,8,4,6,2,6]
[[3,1],[4,1,5,9],[2],[6,5,3,5],[8,9,7,9,3],[2,3],[8],[4],[6],[2],[6]]

答案 1 :(得分:2)

我非常喜欢基于“休息”这个术语的名字,正如亚当斯所说的那样。该功能有很多可能的变种。这是我期望的(基于F#库中使用的命名)。

一个名为breakBefore的函数将占用一个元素,之前它应该断开:

breakBefore :: Eq a => a -> [a] -> [[a]] 

具有With后缀的函数将采用某种函数直接指定何时中断。如果是brekaing,这是您想要的函数a -> Bool

breakBeforeWith :: (a -> Bool) -> [a] -> [[a]]

你还可以想象一个带有By后缀的函数会带一个键选择器并在键发生变化时中断(有点像group by,但你可以拥有具有相同密钥的多个组):

breakBeforeBy :: Eq k => (a -> k) -> [a] -> [[a]]

我承认名字有点长 - 也许唯一真正有用的功能是你想要的。但是,F#库似乎非常一致地使用这种模式(例如sortsortBy采用密钥选择器,sortWith采用比较器功能)。

也许有可能将这三种变体用于更多的列表处理函数(并且为这三种类型提供一些一致的命名模式是非常好的。)