higher order function haskell

  • A+
Category:Languages

I'm new to Haskell, I've to do a function that counts the number of vowels in a string using the higher order function foldr

I've tried to create this function

vowels [] = 0 vowels (x:xs)= if elem x "aeiou" then 1 + vowels xs else vowels xs 

But it doesn't work and I'm not able to do it using foldr, any suggestion?

 


Well a foldr :: (a -> b -> b) -> b -> [a] -> b is a function where the first parameter is a function f :: a -> b -> b. You can here see the a parameter as the "head" of the list, the second parameter b as the result of the recursion with foldr, and you thus want to produce a result in terms of these two for the entire function. This logic is basically encapsulated in the second clause of your function.

Indeed:

vowels (x:xs) = if elem x "aeiou" then 1 + vowels xs else vowels xs 

can be rewritten as:

vowels (x:xs) = if elem x "aeiou" then 1 + rec else rec     where rec = vowels xs

and rec is thus the outcome of the recursive call, the second parameter of the "fold"-function. x on the other hand is the first parameter of the "fold"-function. We thus need to write this function, only in terms of x and rec, and this is simply:

/x rec -> if elem x "aeiou" then 1 + rec else rec

Furthermore we need to handle the case of an empty list, this is the first clause of your function. In that case the result is 0, this is the second paramter of the foldr, so we got:

vowels = foldr (/x rec -> if elem x "aeiou" then 1 + rec else rec) 0

Or a more clean syntax:

vowels = foldr f 0     where f x rec | elem x "aeiou" = 1 + rec                   | otherwise = rec

We can further clean it up, by abstracting away rec:

vowels = foldr f 0     where f x | elem x "aeiou" = (1+)               | otherwise = id

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: