Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to perform a check on vowels?

Tags:

haskell

I am trying to write a function score :: Char -> Int that converts a character to its score. Each letter starts with a score of 1; 1 is added to the score of a character if it is a vowel (a, e, i, o, u) and 1 is added to the score of a character if it is upper case; a character that is not a letter scores 0. For example,

score 'A' == 3
score 'a' == 2
score 'B' == 2
score 'b' == 1
score '.' == 0

This is my code so far:

n :: Int -> Int
n = 0

isVowel :: Char -> Char
isVowel x = [if x == 'a' || x == 'e' || x == 'i' ||
                x == 'o' || x == 'u' then x else x]

score :: Char -> Int
score x  =
    [if isAlpha x then n+1 else n ]
    [if isUpper x then n+1 else n ]
    [if isVowel x then n+1 else n ]

something is definitely wrong with this code, but I cannot find what. Specifically, is there any way to write a function for detecting vowels? I'm not even sure that the one I wrote is correct. Or do I change the type of isVowel to Char -> Bool then if isVowel = True will that work? I will be thankful for any help provided

like image 302
idontknowhowtocode Avatar asked Dec 30 '25 16:12

idontknowhowtocode


1 Answers

You are writing expression in a (singleton) list. Furthermore your isVowel should return a Bool. We thus can implement this as:

isVowel :: Char -> Bool
isVowel x = x == 'a' || x == 'e' || x == 'i' || x == 'o' || x == 'u'

You however forgot the uppercase vowels (AEIOU) We can write this more compact with an elem check:

isVowel :: Char -> Bool
isVowel x = x `elem` "aeiouAEIOU"

or even with a section of an infix operator:

isVowel :: Char -> Bool
isVowel = (`elem` "aeiouAEIOU")

In your score function you seem to use a variable n but that variable is not defined somewhere, and furthermore in Haskell all variables are immutable: once assigned a value, you can no longer change its value.

We can calculate the score by adding three items together:

score :: Char -> Int
score x  = (if isAlpha x then 1 else 0) + (if isUpper x then 1 else 0) + (if isVowel x then 1 else 0)

Since Bool is a member of the Enum typeclass where False maps to 0 and True maps to 1, we can make use of fromEnum :: Enum a => a -> Int to automatically do the conversion:

score :: Char -> Int
score x  = fromEnum (isAlpha x) + fromEnum (isUpper x) + fromEnum (isVowel x)

or, as @leftroundabout says: we can also make use of list comprehension and work with a list of checks, so:

score :: Char -> Int
score x  = length [ 1 | p <- [isAlpha, isUpper, isVowel], p x ]
like image 199
Willem Van Onsem Avatar answered Jan 02 '26 10:01

Willem Van Onsem



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!