How would I use the greater or less than sign as a variable so that when I enter Main> mySort (<) [1,5,3,6,4,1,3,3,2]
or Main> mySort (>) [1,5,3,6,4,1,3,3,2]
it will sort the list from highest to lowest or lowest to highest depending on which sign I chose to enter?
Asked
Active
Viewed 213 times
-1
-
WHat does ** ( ) ** do? – Martinsos Apr 24 '13 at 02:02
-
Was ment to make it bold – user2313601 Apr 24 '13 at 02:04
-
3See here: http://stackoverflow.com/questions/16101710/sorting-in-haskell-with-parameter-using-higher-order-function (someone in your class?) – hammar Apr 24 '13 at 02:05
2 Answers
4
You can just pass (<)
in and use it compare each value.
A similar function
mySort :: (a -> a -> Ordering) -- Comparator function
-> [a]
-> [a]
And Haskell is so smart that this already exists as sortBy
. This lets you pass in a function returning an Ordering
which is just
data Ordering = LT | EQ | GT deriving(...)
But you have functions a -> a -> Bool
so you need to make this into an ordering and then you can use it with sortBy
.
wrap f a b | not $ f a b || f b a = EQ
| f a b = LT
| otherwise = GT
Now you can use this to wrap (<)
and (>)
to lift it to be used with sortBy
mySort :: (a -> a -> Bool) -> [a] -> [a]
mySort = sortBy . wrap

daniel gratzer
- 52,833
- 11
- 94
- 134
-
I think `wrap`'s guards would be nicer as `| f a b = LT`, `| f b a = GT` then `| otherwise = EQ`. – AndrewC Apr 24 '13 at 21:10
0
There already is a function in Data.List that does very similar thing to what you want, it is called sortBy.
However if you really want to implement it you could use sortBy like this:
mySort cop ls = sortBy (\a b -> if (cop a b) then LT else GT) ls
or even shorter (using eta reduction):
mySort cop = sortBy (\a b -> if (cop a b) then LT else GT)

Martinsos
- 1,663
- 15
- 31
-
1This is defeats the entire point of having higher order functions... – daniel gratzer Apr 24 '13 at 02:07
-
@jozefg Could you explain please? You are talking about passing function as an argument? Question I was answering was asking only for < and > so I didn't think it is needed to make it work for all kinds of functions. If question was to create a sort that accepts comparison function as an operator, then I agree this would not be a good idea. – Martinsos Apr 24 '13 at 02:11
-
6Higher order functions let you do this sort of thing generically, what sortBy actually does is take a **function** and use that to produce the ordering, it's type sig is `sortBy :: (a -> a -> Ordering) -> [a] -> [a]` This is much lighter weight and more typesafe, using your method you could pass in ` '*' ` or something into your function and get a runtime error with no idea where it came from – daniel gratzer Apr 24 '13 at 02:12
-
@jozefg You are right, I also missused sortBy. I think it should be ok now – Martinsos Apr 24 '13 at 02:18