Прежде, ваше имя sortEm
функции вводит в заблуждение, он не сортирует свой список аргументов, но i nserts его головной элемент в хвост. Как это происходит, есть insert
функция уже в Data.List
module, которая вставляет свой первый аргумент в 2, таким образом есть равноценности
sortEm (x:xs) === Data.List.insert x xs
Теперь, вставка элемента будет только вам отсортированный список обратно, если вы вставка это в список, который уже отсортирован. Поскольку пустой список отсортирован, вот что делает функция myList
, которую вы получили в ответе dave4420. Это "insertion" sort, постепенно вставляя элементы списка во вспомогательный список, изначально пустой. И это то, что вторая функция делает, что вы получили в dave4420 ответ:
insertionSort xs = foldr Data.List.insert [] xs
Это «применяется sortem», т.е. вставки, «каждый элемент» только один раз. Для получения списка [a,b,c,...,z]
это эквивалентно
insert a (insert b (insert c (... (insert z []) ...)))
То, что вы, вероятно, означало в ваш комментарий, то для сравнения (и, возможно, подкачка) два соседних элемента «только один раз», известен как bubble sort. Конечно, делает только один проход по списку не будет выкручиваться, в общем случае:
bubbleOnce xs = foldr g [] xs where
g x [] = [x]
g x [email protected](y:ys) | x>y = y:x:ys -- swap x and y in the output
| otherwise = x:xs -- keep x before y in the output
Теперь bubbleOnce [4,2,6,1,8] ==> [1,4,2,6,8]
. Значение, которое вы ожидали, [2,4,1,6,8]
, было бы результатом применения функции складывания g
в противоположном направлении, слева направо. Но это гораздо менее естественно, чтобы сделать здесь с Haskell списки:
bubbleOnce' [] = []
bubbleOnce' (x:xs) = let (z,h)=foldl g (x,id) xs in (h [z]) where
g (x,f) y | x>y = (x, f.(y:)) -- swap x and y in the output
| otherwise = (y, f.(x:)) -- keep x before y in the output
(редактировать :) см jimmyt's answer в эквиваленте, но простой и хороший вариант с использованием простой рекурсии.Он также более ленивый (менее строгий), чем версии fodlr
и foldl
.
, если вы просто ищете образцы кода, попробуйте [Грамотные программы] (http://en.literateprograms.org/index.php?title=Special%3ASearch&search=sort+haskell) или [Rosetta код ] (http://rosettacode.org/mw/index.php?title=Special%3ASearch&search=sort). –
'sortEm [5,4,3,2,1]' приводит к '[4,3,2,1,5]' --- не пустой список или список отдельных элементов. Можете ли вы прояснить, какова ваша проблема? – dave4420
как бы применить sortEm к каждому элементу в списке? И спасибо Даниилу за ссылки, прочитав какой-то код, синтаксис Haskell прекрасен. – Bjern