`pred` of Char in List[Char] - scalaz

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).

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>

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.
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

How to make tail function return what I need?

I need to encode list in OCaml. Command: encode ['a','a','b','b','b','c'];; have to return [(2,'a');(3,'b');(1,'c')]
Now I have this function:
let encode list =
let rec encodeHelper list acc = match list with
| [] -> []
| head :: [] -> (1, head) :: []
| head :: headNext :: tail -> if (head = headNext) then encodeHelper (headNext :: tail) (acc + 1)
else (acc, head) :: encodeHelper (headNext :: tail) acc
in encodeHelper list 1
;;
But it returns:
: (int * (char * char * char * char * char * char)) list =
[(1, ('a', 'a', 'b', 'b', 'b', 'c'))]
Your test data as shown at the top is not in the right form.
A list in OCaml has elements separated by semicolons (;). Your test data is using commas instead (,). Commas are used for tuples, which is why you're seeing a tuple in your result.
If you change , to ; in your test data you should see something closer to what you're looking for. There is at least one problem left to fix (in my testing).

The type signature for `isprime' lacks an accompanying binding

I have this code:
esprimo :: Int->Bool
esPrimo x = if length (div x x) == 2 then True else False
But I pulled the error is above
In addition to what sibi said, I think what you are trying to do is this:
isPrime :: Int -> Bool
isPrime x = if length [d | d <- [1..x], x `mod` d == 0] == 2 then True else False
this is basically the direct translation of the mathematical concept of beeing prime into Haskell.
As you don't need the if as it checks the same == already returns a bit more readable might be:
isPrime :: Int -> Bool
isPrime x = length divisors == 2
where divisors = [d | d <- [1..x], x `isMultipleOf` d]
isMultipleOf m n = m `mod` n == 0
Please note that this is of course not the most performant prime-test.
The exact reason for your error is because of the different cases you have used in the type signature and the type definition:
esprimo :: Int -> Bool -- p should be capital here to work.
esPrimo x = if length (div x x) == 2 then True else False
Haskell is case sensitive, so esprimo and esPrimo are different. That being said there is other type error in your code: the type of div is div :: Integral a => a -> a -> a, so it returns a and you are applying length function on it. But length function only accepts list i.e [a] and not a which will produce you type error.