2013-04-24 15 views
-1

Как использовать знак большего или меньшего размера как переменную, чтобы при вводе Main> mySort (<) [1,5,3,6,4,1,3,3,2] или Main> mySort (>) [1,5,3,6,4,1,3,3,2] он будет сортировать список от наивысшего до самого низкого или самого низкого до самого высокого в зависимости от того, какой знак я выбрал для ввода?Как использовать '(<)' как переменную?

+0

, что делает **() ** делать? – Martinsos

+0

Был ли смысл делать это полужирным шрифтом – user2313601

+3

См. Здесь: http://stackoverflow.com/questions/16101710/sorting-in-haskell-with-parameter-using-higher-order-function (кто-то из вашего класса?) – hammar

ответ

0

В Data.List есть функция, которая очень похожа на то, что вы хотите, она называется sortBy.
Однако, если вы действительно хотите, чтобы реализовать его можно использовать SortBy так:

mySort cop ls = sortBy (\a b -> if (cop a b) then LT else GT) ls 

или даже короче (с использованием сокращения ETA):

mySort cop = sortBy (\a b -> if (cop a b) then LT else GT) 
+1

Это поражает всю точку с функциями более высокого порядка ... – jozefg

+0

@jozefg Не могли бы вы объяснить, пожалуйста? Вы говорите о передаче функции в качестве аргумента? Вопрос, на который я отвечал, запрашивал только < and >, поэтому я не думал, что это необходимо для того, чтобы он работал для всех видов функций. Если бы вопрос заключался в том, чтобы создать сортировку, которая принимает функцию сравнения в качестве оператора, то я согласен, что это не будет хорошей идеей. – Martinsos

+6

Функции более высокого порядка позволяют делать такие вещи в общем случае, что sortBy на самом деле делает ** функцию ** и использовать ее для создания порядка, это тип sig - 'sortBy :: (a -> a -> Ordering) -> [a] -> [a] 'Это гораздо более легкий вес и больше типов, используя ваш метод, который вы могли бы передать в' '* '' или что-то в свою функцию и получить ошибку времени выполнения, не имея представления, откуда она взялась из – jozefg

4

Вы можете просто передать (<) в и использовать его сравнить каждое значение.

Аналогичная функция

mySort :: (a -> a -> Ordering) -- Comparator function 
     -> [a] 
     -> [a] 

И Haskell настолько умны, что уже существует как sortBy. Это позволяет передавать в функции возвращающий Ordering, которая просто

data Ordering = LT | EQ | GT deriving(...) 

Но у вас есть функции a -> a -> Bool, так что вы должны сделать это в упорядочении, а затем вы можете использовать его с sortBy.

wrap f a b | not $ f a b || f b a = EQ 
      | f a b    = LT 
      | otherwise   = GT 

Теперь вы можете использовать это, чтобы обернуть (<) и (>), чтобы поднять его, чтобы использоваться с sortBy

mySort :: (a -> a -> Bool) -> [a] -> [a] 
mySort = sortBy . wrap 
+0

Я думаю, что охранники 'wrap' будут лучше, чем' | f a b = LT', '| f b a = GT' then '| иначе = EQ'. – AndrewC

Смежные вопросы