Haskell 如何调用拆分列表的函数?
我想编写一个函数,根据满足给定属性Haskell 如何调用拆分列表的函数?,haskell,f#,functional-programming,sml,split,Haskell,F#,Functional Programming,Sml,Split,我想编写一个函数,根据满足给定属性p的项将列表拆分为子列表。我的问题是如何调用函数。我将在Haskell中给出示例,但在F#或ML中也会出现同样的问题 连接的子列表是原始列表: concat (split p xss) == xs 每个子列表都满足initial\u p_only p属性,也就是说(A)子列表以满足p的元素开始,因此不是空的,并且(B)没有其他元素满足p: initial_p_only :: (a -> Bool) -> [a] -> Bool initial
p
的项将列表拆分为子列表。我的问题是如何调用函数。我将在Haskell中给出示例,但在F#或ML中也会出现同样的问题
连接的子列表是原始列表:
concat (split p xss) == xs
每个子列表都满足initial\u p_only p
属性,也就是说(A)子列表以满足p
的元素开始,因此不是空的,并且(B)没有其他元素满足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
,拆分将失败
此函数需要调用
split
以外的其他函数我该怎么称呼它呢???我相信您描述的函数是包中的breakBefore
数据.列表.分组
:
正如亚当斯所说,我很喜欢一些基于“休息”这个词的名字。该函数有很多可能的变体。以下是我所期望的(基于F#libraries中使用的命名) 名为just
breakBefore
的函数将接受一个元素,它应该在该元素之前中断:
breakBefore :: Eq a => a -> [a] -> [[a]]
带有后缀的函数将采用某种直接指定何时中断的函数。对于brekaing,这是您想要的函数a->Bool
:
breakBeforeWith :: (a -> Bool) -> [a] -> [[a]]
您还可以想象一个后缀为By
的函数将使用一个键选择器并在键更改时中断(这有点像groupby
,但您可以使用同一个键创建多个组):
我承认名字有点长了,也许唯一真正有用的函数就是你想要的。然而,F#库似乎一直在使用这种模式(例如,排序
,排序
使用键选择器和排序
使用比较器功能)
也许可以为更多的列表处理函数使用这三种变体(最好为这三种类型使用一致的命名模式)。groupBy似乎不太正确。groupAt可能会起作用。我喜欢你在没有实现的情况下编写正式规范的方式。如果来得有点晚,我很抱歉,但我相信你的表述是错误的。“使非法国家不具有代表性”。您应该返回的是(a[a])
列表。您的输入可能也应该是(a[a])
,但原因稍有不同(注意混淆)。如果这是您的问题域中经常出现的主题,那么也值得使用newtypePAndList
和PAndNotPList
来区分这两种类型。+1不仅用于给出名称,而且用于已经存在的函数实现。可怕。我的代码已经编写好了。非常感谢。我不喜欢break
的普通变体,因为break
本身产生一个元组而不是列表。可能是在
之前中断,但复数太微妙了UnfollowBreaks
是一个相当字面的名称。breakBefore
似乎与您的规范不完全匹配,因为breakBefore
不要求结果中第一个分组的第一个元素满足给定谓词,但规范确实要求这样做(否则函数应该失败——这就是规范所说的)。我只是简单地将我的break:('a->bool)->'a list->'a list*'a list
breakBefore :: Eq a => a -> [a] -> [[a]]
breakBeforeWith :: (a -> Bool) -> [a] -> [[a]]
breakBeforeBy :: Eq k => (a -> k) -> [a] -> [[a]]