How to integrate a sum function into my Haskell function? - 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

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>

What is the syntax for different recursions depending on two boolean guards?

I'm very new to Haskell and am trying to write a simple function that will take an array of integers as input, then return either the product of all the elements or the average, depending on whether the array is of odd or even length, respectively.
I understand how to set a base case for recursion, and how to set up boolean guards for different cases, but I don't understand how to do these in concert.
arrayFunc :: [Integer] -> Integer
arrayFunc [] = 1
arrayFunc array
| (length array) % 2 == 1 = arrayFunc (x:xs) = x * arrayFunc xs
| (length array) % 2 == 0 = ((arrayFunc (x:xs) = x + arrayFunc xs) - 1) `div` length xs
Currently I'm getting an error
"parse error on input '='
Perhaps you need a 'let' in a 'do' block?"
But I don't understand how I would use a let here.
The reason you have guards is because you are trying to determine the length of the list before you actually look at the values in the list.
Rather than make multiple passes (one to compute the length, another to compute the sum or product), just compute all of the values you might need, as you walk the list, and then at the end make the decision and return the appropriate value:
arrayFunc = go (0, 1, 0, True)
where go (s, p, len, parity) [] =
if parity then (if len /= 0 then s `div` len else 0)
else p
go (s, p, len, parity) (x:xs) =
go (s + x, p * x, len + 1, not parity) xs
There are various things you can do to reduce memory usage, and the recursion is just reimplementing a fold, but this gives you an idea of how to compute the answer in one pass.
Define an auxiliary inner function like that:
arrayFunc :: [Integer] -> Integer
arrayFunc [] = 1
arrayFunc array
| (length array) % 2 == 1 = go1 array
| (length array) % 2 == 0 = go2 array
where
go1 (x:xs) = x * go1 xs
go2 (x:xs) = ((x + go2 xs) - 1) `div` length xs
This deals only with the syntactical issues in your question. In particular, [Integer] is not an array -- it is a list of integers.
But of course the name of a variable doesn't influence a code's correctness.
Without focus on recursion this should be an acceptable solution:
arrayFunc :: (Integral a) => [a] -> a
arrayFunc ls
| n == 0 = 1
| even n = (sum ls) `div` (fromIntegral n)
| otherwise = product ls
where
n = length xs

Average of user input

I want to take the user input of a list of numbers and find the average. However, after looking for examples I have not found any that seems to match what I am doing because I can have from 2 - 100 numbers in a list. Any help/advice is appreciated.
Below is my working code as is.
main = do
putStrLn "Enter how many numbers:"
listlen <- getLine
if ((read listlen) <= 100) -- read converts a string to a number
then do
putStrLn "Enter a String of numbers:"
--numberString <- getLine
numberString<- getLine
let ints = map read (words numberString) :: [Int]
putStrLn("The List: " ++(numberString))
putStrLn("The average: ")
putStrLn("Number of values greater than average: ")
else do
putStrLn " Error: listlen must be less than or = to 100"
main
Ok, this is homework, but homework can be really tough when you have to do it in Haskell. I'll try to explain step by step how you can do.
Good to know
First, Haskell is functional. You can find different defintions of "functional", but basically you can think of it as a property of the language: everything is constant (no side effect).
Second, you can start a REPL by typing ghci in a terminal:
jferard#jferard-Z170XP-SLI:~$ ghci
GHCi, version 8.0.2: http://www.haskell.org/ghc/ :? for help
Prelude> :set +m -- enable parsing of multiline commands
Prelude> -- type the expression you want to evaluate here
Recursion
How do you compute the sum of the elements of a list? In an imperative language, you will do something like that (Python like):
s = 0
for every x in xs:
s <- s + x
But s is not constant. It's updated on every iteration until we get the sum. Can we reformulate the algorithm to avoid this mutation? Fortunately yes. Here's the key idea:
sum [x] = x
sum [x1, ..., xn] = x1 + sum [x2, ..., xn]
With a little imagination, you can say that sum [] = 0. So we can write it in Haskell:
sum [] = 0
sum (x:xs) = x + sum xs
-- sum [1, 2, 3, 5] == 11
(x:xs) means: x (the head) followed by the list xs (the tail). If you have understood that, you know how we can avoid side effects in many situations: just call another function to do the rest of the job. (Note: if you know about the stack, you can imagine what happens under the hood.)
Now, how do you compute the length of a list? In a Python-like language, you'd do something like (forget len(..)):
l = 0
for every x in xs:
l <- l + 1
Again, with a recursive definition, you have:
length [] = 0
length (x:xs) = 1 + length xs
-- len [1, 2, 3, 5] == 4
Folds
Computing sum and length is so common that they are built-in functions in Haskell. But there is something more important: if you examine the two functions carefully, you'll notice this pattern:
f [] = <initial value>
f (x:xs) = g(f xs, x)
For sum, initial value is 0 and g(f xs, x) = x + f xs. For length, initial value is 0 and g(f xs, x) = 1 + f xs. This pattern is so common that Haskell has a built-in function (actually several built-in functions) for it: foldl. foldl takes a function, an initial value and a list and returns the function repeatedly applied to the previous result and the current element, until the list is consumed. You can think of the function as the the body of the loop:
sum xs = foldl (+) 0 xs
(Note on curryfication: 1. You will maybe learn some day that Haskell functions always take one argument, but that's not the point here. 2. You can remove xs on both sides: sum = foldl (+) 0)
Prelude> foldl (+) 0 [1,2,3,5]
11 -- (((0+1)+2)+3)+5
With scanl, you can in some way "debug" the foldl:
Prelude> scanl (+) 0 [1,2,3,5]
[0,1,3,6,11]
length is more tricky, since you don't have a built-in function g(f xs, x) = 1 + f xs. You can use a lambda function: \acc x -> 1 + acc where acc is the current value:
length xs = foldl (\acc x -> 1 + acc) 0 xs
Your question
Average
Let's try to write average with the built-in sum and length functions:
Prelude> average xs = sum xs / length xs
<interactive>:1:14: error:
• Could not deduce (Fractional Int) arising from a use of ‘/’
...
What does that mean? I won't get into details, but you have to know that Haskell is very strict with numbers. You can't divide two integers and expect a float result without a little work.
Prelude> :t (/)
(/) :: Fractional a => a -> a -> a
This means that / will take Fractionals. Thus, the work is: cast integers into Fractionals.
average xs = fromIntegral (sum xs) / fromIntegral (length xs)
-- average [1, 2, 3, 5] == 2.75
Number of values greater than average
Now, the number of values greater than the mean. In a Python-like langage, you'll write:
c = 0
for every x in xs:
if x > avg:
c <- c + 1
Let's try the recursive method:
gtAvg [] = 0
gtAvg (x:xs) = (if x>avg then 1) + sum xs -- WRONG
You see that there is something missing. In the imperative version, if x <= avg, we simply do nothing (and thus do not update the value). Here, we must return something:
gtAvg [] = 0
gtAvg (x:xs) = (if x>avg then 1 else 0) + gtAvg xs
But where does the avg value come from? We need to precompute it. Let's define a function that takes avg as an argument:
gtAvg' [] _ = 0
gtAvg' (x:xs) avg = (if fromIntegral x>avg then 1 else 0) + gtAvg' xs avg
-- gtAvg' [1, 2, 3, 5] (average [1, 2, 3, 5]) == 2
And then:
gtAvg xs = gtAvg' xs (average xs)
-- gtAvg [1, 2, 3, 5] == 2
Obviously, this is more simple with a foldl:
gtAvg xs = foldl (\acc x -> if fromIntegral x>average xs then acc+1 else acc) 0 xs
More (map, filter and list comprehension)
When we are on the basics of Haskell, you may need three more constructs.
Filter
First, a filter:
Prelude> filter (>2.75) [1, 2, 3, 5]
[3.0,5.0]
If you take the length of that list, you get the number of elements greater than the average:
gtAvg xs = length $ filter (\x -> fromIntegral x >average xs) xs
(Or with a composition of functions: length $ filter ((> average xs).fromIntegral) xs) Don't be disturbed by the $ sign: it means that the right side of the expression (filter...) is one block, like if it were in parenthesis.
Map
Second, map applies a function to every element of a list and returns the list of mapped elements. For instance, if you want to some squares of elements of a list:
Prelude> sum $ map (**2) [1, 2, 3, 5]
39.0
You can use it like that:
gtAvg xs = length $ filter (>average xs) $ map fromIntegral xs
It converts elements to Fractional, then it applies the filter.
List comprehension
Third, you can have filter and a map with a list comprehension:
gtAvg xs = length [x | x<-xs, fromIntegral x>average xs]
I left a lot of things aside and made probably approximations, but now you should have the basic knowledge to answer your question.
listlen :: [a] -> Int
listlen xs = go 0 xs -- 0 = initial value of accumulator
where go s [] = s -- return accumulator
go s (a:as) = go (s+1) as -- compute the next value of the accumulator
sumx :: [a] -> Int
sumx xs = go 0 xs
where go s [] = s
go s (a:as) = go ... as -- flll in the blank ... -- and recurse
lenAndSum :: [a] -> (Int,Int)
lenAndSum xs = go (0,0) xs -- (0,0) = initial values of both accumulators
where go (s1,s2) [] = (s1,s2) -- return both accumulators at the end
go (s1,s2) (a:as) = go ... as -- left as an exercise
main = do
putStrLn "Enter how many numbers:"
listlen <- getLine
if ((read listlen) <= 100) -- read converts a string to a number
then do
putStrLn "Enter a String of numbers:"
--numberString <- getLine
numberString<- getLine
let ints = map read (words numberString) :: [Int]
putStrLn("The List: " ++(numberString))
putStrLn("The average: ")
putStrLn("Number of values greater than average: ")
else do
putStrLn " Error: listlen must be less than or = to 100"
main`enter code here`

How to create a Prouhet–Thue–Morse sequence in Haskell?

I'm a noob in Haskell, but some experience with ActionScript 3.0 Object Orientated. Thus working on a major programming transition. I've read the basic knowledge about Haskel, like arithmetics. And I can write simple functions.
As a practical assignment I have to generate the Thue-Morse sequence called tms1 by computer in Haskell. So it should be like this:
>tms1 0
0
>tms1 1
1
>tms1 2
10
>tms1 3
1001
>tms1 4
10010110
and so on... According to wikipedia I should use the formula.
t0 = 0
t2n = tn
t2n + 1 = 1 − tn
I have no idea how I can implement this formula in Haskell. Can you guide me to create one?
This is what I got so far:
module ThueMorse where
tms1 :: Int -> Int
tms1 0 = 0
tms1 1 = 1
tms1 2 = 10
tms1 3 = 1001
tms1 x = tms1 ((x-1)) --if x = 4 the output will be 1001, i don't know how to make this in a recursion function
I did some research on the internet and found this code.
Source:
http://pastebin.com/Humyf6Kp
Code:
module ThueMorse where
tms1 :: [Int]
tms1 = buildtms1 [0] 1
where buildtms1 x n
|(n `rem` 2 == 0) = buildtms1 (x++[(x !! (n `div` 2))]) (n+1)
|(n `rem` 2 == 1) = buildtms1 (x++[1- (x !! ((n-1) `div` 2))]) (n+1)
custinv [] = []
custinv x = (1-head x):(custinv (tail x))
tms3 :: [Int]
tms3 = buildtms3 [0] 1
where buildtms3 x n = buildtms3 (x++(custinv x)) (n*2)
intToBinary :: Int -> [Bool]
intToBinary n | (n==0) = []
| (n `rem` 2 ==0) = intToBinary (n `div` 2) ++ [False]
| (n `rem` 2 ==1) = intToBinary (n `div` 2) ++ [True]
amountTrue :: [Bool] -> Int
amountTrue [] = 0
amountTrue (x:xs) | (x==True) = 1+amountTrue(xs)
| (x==False) = amountTrue(xs)
tms4 :: [Int]
tms4= buildtms4 0
where buildtms4 n
|(amountTrue (intToBinary n) `rem` 2 ==0) = 0:(buildtms4 (n+1))
|(amountTrue (intToBinary n) `rem` 2 ==1) = 1:(buildtms4 (n+1))
But this code doesn't give the desired result. Any help is well appreciated.
I would suggest using a list of booleans for your code; then you don't need to explicitly convert the numbers. I use the sequence defined like this:
0
01
0110
01101001
0110100110010110
01101001100101101001011001101001
...
Notice that the leading zeros are quite important!
A recursive definition is now easy:
morse = [False] : map step morse where step a = a ++ map not a
This works because we never access an element that is not yet defined. Printing the list is left as an excercise to the reader.
Here is another definition, using the fact that one can get the next step by replacing 1 with 10 and 0 with 01:
morse = [False] : map (concatMap step) morse where step x = [x,not x]
Edit
Here are easier definitions by sdcvvc using the function iterate. iterate f x returns a list of repeated applications of f to x, starting with no application:
iterate f x = [x,f x,f (f x),f (f (f x)),...]
And here are the definitions:
morse = iterate (\a -> a ++ map not a) [False]
morse = iterate (>>= \x -> [x,not x]) [False]
Your definition of the sequence seems to be as a sequence of bit sequences:
0 1 10 1001 10010110 ... etc.
t0 t1 t2 t3 t4
but the wikipedia page defines it as a single bit sequence:
0 1 1 0 1 ... etc
t0 t1 t2 t3 t4
This is the formulation that the definitions in Wikipedia refer to. With this knowledge, the definition of the recurrence relation that you mentioned is easier to understand:
t0 = 0
t2n = tn
t2n + 1 = 1 − tn
In English, this can be stated as:
The zeroth bit is zero.
For an even, non-zero index, the bit is the same as the bit at half the index.
For an odd index, the bit is 1 minus the bit at half the (index minus one).
The tricky part is going from subscripts 2n and 2n+1 to odd and even, and understanding what n means in each case. Once that is done, it is straightforward to write a function that computes the *n*th bit of the sequence:
lookupMorse :: Int -> Int
lookupMorse 0 = 0;
lookupMorse n | even n = lookupMorse (div n 2)
| otherwise = 1 - lookupMorse (div (n-1) 2)
If you want the whole sequence, map lookupMorse over the non-negative integers:
morse :: [Int]
morse = map lookupMorse [0..]
This is the infinite Thue-Morse sequence. To show it, take a few of them, turn them into strings, and concatenate the resulting sequence:
>concatMap show $ take 10 morse
"0110100110"
Finally, if you want to use the "sequence of bit sequences" definition, you need to first drop some bits from the sequence, and then take some. The number to drop is the same as the number to take, except for the zero-index case:
lookupMorseAlternate :: Int -> [Int]
lookupMorseAlternate 0 = take 1 morse
lookupMorseAlternate n = take len $ drop len morse
where
len = 2 ^ (n-1)
This gives rise to the alternative sequence definition:
morseAlternate :: [[Int]]
morseAlternate = map lookupMorseAlternate [0..]
which you can use like this:
>concatMap show $ lookupMorseAlternate 4
"10010110"
>map (concatMap show) $ take 5 morseAlternate
["0", "1", "10", "1001", "10010110"]
Easy like this:
invertList :: [Integer] -> [Integer]
invertList [] = []
invertList (h:t)
|h == 1 = 0:invertList t
|h == 0 = 1:invertList t
|otherwise = error "Wrong Parameters: Should be 0 or 1"
thueMorse :: Integer -> [Integer]
thueMorse 1 = [0]
thueMorse n = thueMorse (n - 1) ++ invertList (thueMorse (n - 1))