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
?
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.