I have to write a function like this minByFunction (\x -> -x) [1,2,3,4,5] that gives me as an answer 5. Another example would be minBy length ["a", "abcd", "xx"] gives me "a". I though I can solve this with something like this:
minBy :: (a -> Bool) -> [a] -> Int
minBy measure list =
case list of
[] -> 0
(x:xs:rest) -> if measure x > measure xs then minBy measure x:rest else minBy measure xs:rest
CodePudding user response:
You need to use parenthesis for (x:rest)
, otherwise it is interpreted as (minBy measure x) : rest
. Since the two recursive calls have minBy measure
in common, we can however make a if … then … else …
clause for the list with which we make a recursive call.
Furthermore the measure
should not per se return a Bool
, you want to map it on any type b
that is a member of the Ord
typeclass.
You also swapped the recursive calls: in case measure x < measure xs
, then you should recurse with x:rest
and vice versa.
Finally the function should return an a
object, so the base case is a singleton list, not an empty list: for an empty list there is no minimum:
minBy :: Ord b => (a -> b) -> [a] -> a
minBy measure list =
case list of
[x] -> x
(x:x2:xs) -> minBy measure (if measure x > measure x2 then x2:xs else x:xs)