New to haskell. So the first function I made sort_by
sorts a list of type a using quicksort - works fine.
Next function compare by takes in a comparator type (defined below) and a function and returns a comparator - so GT
, EQ
etc. Both of these functions I had to make using just the function definition. Now the problem - I'm supposed to use both these functions to define a function based on the title using currying, but I don't know how my compare_By
function is supposed to help create a function like that?
Any help greatly appreciated. Thanks.
import GHC.Show (Show)
type Comparator a = a -> a -> Ordering
type Tokeniser a = String -> [a]
type Translator a b = a -> Maybe b
data English = E String deriving (Show)
data French = F String deriving (Show)
data German = G String deriving (Show)
sort_by :: Comparator a -> [a] -> [a]
sort_by o as = qs as []
where qs [] as' = as'
qs (a:as) as' = qs les $ a : qs gts as'
where les = [a' | a' <- as, a `o` a' == GT]
gts = [a' | a' <- as, a `o` a' /= GT]
compare_by :: (b -> a) -> Comparator a -> Comparator b
compare_by f o a b = o (f a) (f b)
sort_by_fst :: Comparator a -> [(a,b)] ->[(a,b)]
sort_by_fst f [(a,b)] = ??
When faced with these problems it's helpful to look at the types and work from there.
You need to use sort_by
and compare_by
to create sort_by_fst
. Evidently, we'll need sort_by
to sort the list, so let's see the type of that:
sort_by :: Comparator a -> [a] -> [a]
Great, let's use that to sort the list:
sort_by_fst f xs = sort_by _comparator xs
Looking at the type of sort_by
again, we can see we need a Comparator (a, b)
to sort the xs :: [(a, b)]
. But we only have a f :: Comparator a
, so use compare_by
to get a Comparator (a, b)
.
compare_by :: (b -> a) -> Comparator a -> Comparator b
-- Specialising to the types we need (substituting b = (a, b)):
compare_by :: ((a, b) -> a) -> Comparator a -> Comparator (a, b)
In addition to a Comparator a
, we need a (a, b) -> a
: a function that gets the first element of a tuple. fst
does exactly that:
sort_by_fst f xs = sort_by (compare_by fst f) xs
This could also be written more succinctly as
sort_by_fst = sort_by . compare_by fst
By the way, the _name
(eg _comparator
) syntax is GHC's typed holes feature . If you compile code with a hole, GHC will tell you what type of expression needs to go there and suggests possible bindings (eg functions and parameters) that could fill the hole.
As a side note, the compare_by
function is a specialised and flipped version of on
from Data.Function
:
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
sort_by_fst
could therefore be implemented like this:
import Data.List (sortBy)
import Data.Function (on)
sort_by_fst :: Comparator a -> [(a, b)] -> [(a, b)]
sort_by_fst f = sortBy (f `on` fst)
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.