简体   繁体   中英

How to write my own Haskell sortOn function

I was wondering how to write my own sortOn function.

I made a sortBy function and an on function as shown bellow but can't figure out how to combine them and what additional code to add. sortOn is like sortBy but the given function (in here named comp ) is applied only once for every element of the list

sortBy :: (a -> a -> Ordering) -> [a] -> [a]
sortBy comp [] = []
sortBy comp [x] = [x]
sortBy comp (x:xs) = insert x (sortBy comp xs)
 where 
  insert x [] = [x]
  insert x (y:ys) 
   | (comp x y == LT) || (comp x y == EQ) = x:y:ys
   | otherwise = y:(insert x ys)

on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
on b f x y = b (f x) (f y)

Here's a hint.

If you have a list [a] and you just sort it, the sort function will implicitly make use of the Ord instance for a and specifically the function:

compare :: a -> a -> Ordering

to figure out the relative ordering of pairs of a elements.

Now, if you have a list [a] and a transformation function b , and you want to use sortOn to sort the list of the transformed values, you'll need to figure out the relative ordering of pairs of b elements. How will you do this? Well, you'll implicitly use the Ord instance for b and specifically the function:

compare :: b -> b -> Ordering

In other words, when you try to define:

sortOn :: (Ord b) => (a -> b) -> [a] -> [a]
sortOn f lst = ...

you'll have arguments of type:

f :: a -> b
lst :: [a]

and additional objects of type:

sortBy :: (a -> a -> Ordering) -> [a] -> [a]
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
compare :: b -> b -> Ordering

Now, can you see how to put them together to define sortOn ?

SPOILERS

Further hint: What's the type of compare `on` f ?

Further further hint: It's a -> a -> Ordering .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM