Defining many function values elegantly in haskell - function

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.

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

Related

Haskell function to uppercase the first letter and lowercase the rest of the letters in a word

I have been trying to write a function that capitalizes the first letter and uncapitalized the rest in Haskell. For example, capitalized "mELboURNe" == "Melbourne" but I am getting errors. I have to use list comprehension.
I have tried this,
capitilized :: String -> String
capitilized = map(\x -> if length x == 1 then capitilized3 x else capitilized2 x)
capitilized2 :: Char -> Char
capitilized2 x= Char.toLower x
capitilized3 :: Char -> Char
capitilized3 x= Char.toUpper x
But I am getting this error:
• Couldn't match expected type ‘t0 a0’ with actual type ‘Char’
• In the first argument of ‘length’, namely ‘x’
In the first argument of ‘(==)’, namely ‘length x’
In the expression: length x == 1
|
21 | capitilized = map(\x -> if length x == 1 then capitilized3 x else capitilized2 x)
Can anyone help?
A String is a list of Chars, but a Char is not a list so length x makes no sense.
You can work with pattern matching with:
capitilized :: String -> String
capitilized [] = …
capitilized (x:xs) = …
Here especially the second pattern is important since x will bind with the first Character of the string, and xs with the remaining characters. I leave the … parts as an exercise.

Write a function that replaces the character c to '*'

Condition: Function containing character c and string xs, where all c's are replaced by '*'.
`
zensiert :: [Char] -> String
zensiert c (x:xs)
| x == c = x == '*'
| otherwise = zensiert c (x:xs)
`
The map function and list generators are prohibited. Example: zensiert 'l' ''Rolls a ball around the corner and falls down.'' returns:''Ros a ba around the corner and fas down.''
Because of the example is was thinking that is at the beginning a list in a char that leads to a string, but it didn ´ t work. Because of that I would be very conceivable, if someone would look over there times
Now I tried so:
zensiert :: [Char] -> String
zensiert (x:xs) = if x == 'c' then ('*' : zensiert xs) else (x : zensiert xs)
But there is the problem, if i give zensiert 'l' "Hello", the terminal says: Couldn't match expected type ‘[Char] -> t’ with actual type ‘[Char]’
First, the type signature should be
zensiert :: Char -> String -> String
You'll take a character and a string as arguments, and return a new string.
== is not an assignment operator, even if Haskell did have assignments. Your second definition would be fine (for replacing hard-coded 'c's, anyway), except you don't define it for the empty string the recursive call will eventually receive, and you incorrectly call it with a Char argument it won't use.
The correct definition takes a Char argument and uses that instead of the Char literal 'c'.
zensiert :: Char -> String -> String
zensiert _ [] = []
zensiert c (x:xs) = if x == c then ('*' : zensiert xs) else (x : zensiert xs)
A simpler approach would be to use map to apply a function that replaces 'c' with '*' to a list, whether it is empty or not.
zensiert c xs = map (\x -> if x == c then '*' else x) xs
or
zensiert c xs = map f xs
where f 'c' = '*'
f x = x
Whenever you are defining recursive functions, you need at least one base case that exists the recursion, and at least one case that calls the function recursively in a way that converges on the base case.
If you're dealing with strings, the base case is often an empty string, and we converge the making the input string closer to an empty string.
Replacing any character with '*' in an empty string gives us just an empty string, so the base case is simple. For the update case, we just have to decide what to append to recursively calling the function on the "tail" of the string.
ghci> :{
ghci| subChar _ "" = ""
ghci| subChar c (x:xs)
ghci| | c == x = '*' : subChar c xs
ghci| | otherwise = x : subChar c xs
ghci| :}
ghci> subChar 'l' "world"
"wor*d"
ghci>

How to integrate a sum function into my Haskell function?

My function will replace will any number in the string to 3 and any character to 4. For example "foo123" will be replaced to "444333". My question is how do I convert the "444333" into list in order to use the sum function. "444333" -> [4,4,4,3,3,3] -> sum [4,4,4,3,3,3] = 21
This my code
replaceString [] = []
replaceString (x:xs) =
if x `elem` ['0'..'9']
then '3' :replaceString xs
else if x `elem` ['a'..'z']
then '4' : replaceString xs
else x : replaceString xs
Your replaceString already returns a List of characters but I guess you want to obtain a list of numbers, the answer is just to replace '3' and '4' with 3 and 4 :), so it will become like this :
replaceString [] = []
replaceString (x:xs) = (if x `elem` ['0'..'9']
then 3
else 4) : replaceString xs
Notice that we don't need to repeat : replaceString xs :) .
Alternatively if you want to convert a list of digit characters into a list of numbers you could get character's "ordinal" and subtract 48 from it, in haskell the character's ordinal can be obtained by fromEnum char, with replaceString putting '3' and '4'(instead of numbers), we can define a function like this :
convertToDigits numstr = map ((48 -) . fromEnum) numstr
By the way your original function doesn't convert any other character into 4 but only alphabetic characets, so for foo21! the result would be 44433! and you wouldn't want to sum that, if you want to filter digits I suggest you filter the string from non-alphanumeric characters before even calling replaceString.
Edit :
As Thomas pointed out, you can replace (48 -) . fromEnum with digitToInt (needs to be imported from Data.Char).
This could also be done by foldl as follows;
import Data.Char
getsum :: String -> Int
getsum = foldl helper 0
where helper n c | isLetter c = n + 3
| isNumber c = n + 4
| otherwise = n
If you use map and read it should works great
funct l = map(\x ->read [x]::Int) l
sum funct("444333") = 21

OCaml : Raise an error inside a match with structure

In OCaml, I have a list of strings that contains names of towns (Something like "1-New York; 2-London; 3-Paris"). I need to ask the user to type a number (if they want London they have to type 2).
I want to raise an exception message saying that the town is not valid, if the person types for example "4", in the example.
I tried this, but it doesn't work :
let chosenTown = match int_of_string (input_line stdin) with
| x > (length listOfTowns) -> raise (Err "Not a valid town")
What's the good way to code "if the chosen number is bigger than the length of the list then raise the error" ??
Pattern can't contain arbitrary expressions. It can be a constant, a constructor name, record field inside curly braces, list, array, etc.
But patterns can be guarded, e.g.
match int_of_string (input_line stding) with
| x when x >= length listOfTowns ->
invalid_arg "the number is too large"
| x -> List.nth listOfTowns x
To complete the answer, patter matching relies on unification and does not expect assertion (it is not the equivalent of a switch in C or so).
The idea is that you provide different "shapes" (patterns) that your term (the thing you match on) could have.
For a list for instance:
match l with
| e :: e' :: r -> (*...*)
| e :: r -> (*...*)
| [] -> (*...*)
It also had a binding effect, if you pass on, say, [1] (a very small list indeed), it won't match e :: e' :: r, but will match e :: r and then e = 1 and r = [].
As ivg said, you can add conditions, as booleans this time, thanks to the keyword when.
However, when manipulating lists like this, I would go for a recursive function:
let rec find_town n l =
match l with
| t :: _ when n = 1 -> t
| _ :: r -> find_town (n-1) r
| [] -> raise (Err "Not a valid town")
This is basically writing again List.nth but changing the exception that it raises.

`pred` of Char in List[Char]

Looking at the well-written learning Scalaz, I looked at Enum's:
scala> 'a' |-> 'e'
res20: List[Char] = List(a, b, c, d, e)
I can get its head:
scala> res20(0)
res21: Char = a
And then get its successor:
scala> res20(0).succ
res22: Char = b
But, why's the pred of the head equal to ```?
scala> res20(0).pred
res23: Char = `
And the same for the pred's pred equal to _?
scala> res20(0).pred.pred
res24: Char = _
Char doesn't start at a. You'll see the same results for e.g. ('a' - 1).toChar, which is essentially all Enum's pred is doing (although in a more principled way, without the horrible automatic conversions from Char to Int).