Как вызвать функцию, которая разбивает списки? - PullRequest
5 голосов
/ 26 марта 2011

Я хочу написать функцию, которая разбивает списки на подсписки в зависимости от того, какие элементы удовлетворяют данному свойству 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) никакие другие элементы не удовлетворяют 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. Как мне это назвать?

Ответы [ 2 ]

12 голосов
/ 26 марта 2011

Я полагаю, что описываемая вами функция breakBefore из пакета группирования списков .

Data.List.Grouping: http://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]]
2 голосов
/ 26 марта 2011

Мне очень нравится какое-то имя, основанное на термине "разрыв", как предполагает Адамс. Есть довольно много возможных вариантов функции. Вот что я ожидал (основываясь на именах, используемых в библиотеках F #).

Функция с именем просто breakBefore будет принимать элемент, перед которым она должна сломаться:

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

Функция с суффиксом With будет принимать какую-то функцию, которая прямо указывает, когда нужно прерваться. В случае взлома это функция a -> Bool, которую вы хотели:

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

Можно также представить, что функция с суффиксом By будет принимать селектор ключа и прерываться при изменении ключа (что немного похоже на group by, но вы можете иметь несколько групп с одинаковым ключ):

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

Я признаю, что имена становятся немного длиннее - и, возможно, единственная действительно полезная функция - это та, которую вы хотели. Однако библиотеки F #, похоже, используют этот шаблон довольно последовательно (например, sort, sortBy выбирают ключевой селектор и sortWith выбирают функцию сравнения).

Возможно, возможно иметь эти три варианта для большего количества функций обработки списка (и неплохо было бы иметь некоторый согласованный шаблон именования для этих трех типов).

...