Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Defining many function values elegantly in haskell

I want to define a function that will capitalize all lowercase letters:

yell :: Char -> Char
yell 'a' = 'A'
yell 'b' = 'B'
...
yell 'z' = 'Z'
yell ch = ch

What's the best way to do this? I can make a list of pairs of the appropriate inputs and outputs via zip ['a'..'z'] ['A'..'Z'] but I'm not sure how to turn this into a definition of yell.

I know that lookup is something of an option but then I have to futz with Maybe, and I wonder if there is anything even more elementary available.

like image 359
Diffycue Avatar asked Dec 10 '25 20:12

Diffycue


1 Answers

You can use a guard, and make use of toUpper :: Char -> Char, of the Data.Char module for example:

import Data.Char(toUpper)

yell :: Char -> Char
yell c
    | 'a' <= c && c <= 'z' = toUpper c
    | otherwise = c

for ASCII characters, the uppercase is just masking out the sixth bit (with 0010 0000 as mask). So toUpper is equivalent to chr . (~0x20 .&.) . ord for that specific range.

There are however other characters that have an uppercase variant such as characters with diacritics (àáâãäåæçèéêëìí…), Greek characters (αβγδεζηθικλ…), fullwidth characters (abcdefgh…), etc. These are all converted with toUpper, and can not (all) be converted with this trick.

You can perform a lookup with a lookup structure, like for example a `

import Data.HashMap.Strict(HashMap, fromList)
import qualified Data.HashMap.Strict as HM

items :: HashMap Char Char
items = fromList (zip ['a' .. 'z'] ['A' .. 'Z'])

yell :: Char -> Char
yell c
    | Just y <- HM.lookup c items = y
    | otherwise = c
like image 102
Willem Van Onsem Avatar answered Dec 13 '25 10:12

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!