Haskell. Variable not in scope: howManyTimes :: Integer -> [Integer] -> t - haskell

I wrote a small code, which counts of characters or a numbers in a list and how many times. for example howManyTimes 3 [2, 3, 4, 5, 3, 3, 1, 80, 3] should be 4
This is my code
howManyTimes y [] = 0
howManyTimes y xs = howManyIntern y (x:xs) acc
| x == y = howManyIntern y xs (acc + 1)
| otherwise = howManyIntern y xs acc
And I receive this error message. Variable not in scope: howManyTimes :: Integer -> [Integer] -> t
Can anyone say me a hint?

I have rewrite my code. I do not receive an error any more but output is 0
howManyTimes y xs = howManyIntern y xs 0
where howManyIntern y [] acc = 0
howManyIntern y (x:xs) acc | x == y = howManyIntern y xs (acc + 1)
| otherwise = howManyIntern y xs acc
The output is 0 from above code in comment since the expression:
howManyIntern y [] acc = 0
return 0 whenever it finish the counting. It is easy to be fixed by return acc instead:
howManyIntern y [] acc = acc
An alternative way to do that uses existing functions:
howManyTimes y xs = length $ filter (==y) xs

Related

Issues with two Haskell commands, one attempting to find and print differences in two lists, and one attempting to output the longest length [duplicate]

This question already has answers here:
Better exception for non-exhaustive patterns in case
(2 answers)
Closed last year.
Here is the first one, which is attempting to take two lists and print all the differences between the two .
EX.
> list_diff [1,6,1,3,4,3,5] [3,8,5,4,7,4,8]
[1,6,1,8,7,8]
list_diff :: Eq a => [a] -> [a] -> [a]
list_diff [] [] = []
list_diff x y = list_helper x y
list_helper [] [] = []
list_helper (x:xs) y
| x `elem` y = list_helper xs y
| otherwise = x:(list_helper xs y)
When I run a test for this one (using the example provided above), I reviece the following output:
[1,6,1*** Exception: HW1.hs:(12,1)-(15,39): Non-exhaustive patterns in function list_helper
For the second funtion, I am attempting to take a series of values and determine which list is the longest
EX.
progLanguages =
[ ("CptS121" , ["C"]),
("CptS122" , ["C++"]),
("CptS223" , ["C++"]),
("CptS233" , ["Java"]),
("CptS321" , ["C#"]),
("CptS322" , ["Python", "JavaScript"])]
INPUT: max_count progLanguages
OUTPUT: ("CptS322" , 2)
What I have so far isn't working at all, so needless to say I am stuck.
max_count [] = error "bad"
max_count [x] = x
max_count (x:xs) = x max_helper (max_count xs)
where
max_helper (a,b) (a',b')
| length b > length b' = (a, length b)
| otherwise = (a', length b')
Thanks in advance for any help you can give.
You've defined list_helper:
list_helper [] [] = []
list_helper (x:xs) y
| x `elem` y = list_helper xs y
| otherwise = x:(list_helper xs y)
The warning about non-exhaustive pattern matching means that your function is evaluating arguments that you haven't told it how to handle. In this case, that's the first argument being an empty list, but the second argument not being empty.
You need to handle this pattern:
list_helper [] [] = []
list_helper [] y = y
list_helper (x:xs) y
| x `elem` y = list_helper xs y
| otherwise = x:(list_helper xs y)
Prelude> :{
Prelude| list_helper [] [] = []
Prelude| list_helper [] y = y
Prelude| list_helper (x:xs) y
Prelude| | x `elem` y = list_helper xs y
Prelude| | otherwise = x:(list_helper xs y)
Prelude| :}
Prelude> list_helper [1, 2, 3] [4, 5, 6]
[1,2,3,4,5,6]

Subtraction with carry of positive numbers

Given two lists of digits such as [1, 2, 0] = 120 and [1,0,1] = 101, my function sub should return the list [1, 9] = 19 but the function is returning [2, -1] instead. How do I solve this carry problem? It works fine when there isn't a carry and it only receives positive numbers.
Here's the code I have:
sub_Carry :: Integer -> [Integer] -> [Integer] -> [Integer]
sub_Carry c x []
| c == 0 = x
| otherwise = sub_Carry 0 [c] x
sub_Carry c [] x
| c == 0 = x
| otherwise = sub_Carry 0 x [c]
sub_Carry c (x : xs) (y : ys) = (x - y) : sub_Carry c xs ys
sub :: [Integer] -> [Integer] -> [Integer]
sub op1 op2
| to_Integer(op1) == to_Integer(op2) = [0]
| to_Integer(op1) > to_Integer(op2) = drop_Zeros (reverse (sub_Carry 0 (reverse op1) (reverse op2)))
| otherwise = [-1] ++ drop_Zeros (reverse (sub_Carry 0 (reverse op1) (reverse op2)))
Other considerations:
I've have other utility functions such as to_Integer that converts the list into it's correspondent integer, drop_Zeros that removes zeros to the right of the list ([0, 1, 0] = [1, 0])
in the case the result is a negative number it should return the list with -1 at the head ([1, 0, 0] - [1, 0, 1] = [-1, 1])
I noticed that you don't use the parameter c for carrying. It is the central point of the exercise. It is also necessary to solve the case when the list of a parameter y ends earlier than x. My program works only for positive results. So I also modified the function sub to reverse parameters when op1 < op2. Now there should be always a positive result, which you then negate using the constant -1.
sub_Carry :: Integer -> [Integer] -> [Integer] -> [Integer]
sub_Carry 0 [] [] = []
sub_Carry c x [] = sub_Carry c x [0]
sub_Carry c (x : xs) (y : ys)
| (x - y - c) < 0 = (10 + x - y - c) : sub_Carry 1 xs ys
| otherwise = (x - y - c ) : sub_Carry 0 xs ys
sub :: [Integer] -> [Integer] -> [Integer]
sub op1 op2
| to_Integer(op1) == to_Integer(op2) = [0]
| to_Integer(op1) > to_Integer(op2) = drop_Zeros (reverse (sub_Carry 0 (reverse op1) (reverse op2)))
| otherwise = [-1] ++ drop_Zeros (reverse (sub_Carry 0 (reverse op2) (reverse op1)))

What is the "Parse error in pattern" in my Credit Card Validation written in Haskell?

The goal is to validate a list of numbers (credit card number for example ) to first initiate it, reverse it, and then double it, and that would give the sum. Then it would tell if it is valid or in-valid. I have written the code but it wont compile right. It keeps saying this: test.hs:22:1: Parse error in pattern: sumNum.
Here is my code:
main = do
toDigits :: Integer -> [Integer]
toDigitsRev :: Integer -> [Integer]
toDigitsRev n
where
n <= 0 = []
otherwise = n `mod` 10 : toDigitsRev (n `div` 10)
toDigits = reverse . toDigitsRev
double :: [Integer] -> [Integer]
double [] = []
double (x:[]) = [x]
double (x:y:zs) = x : (2 * y) : double zs
doubleRev = reverse . double . reverse
sumNum :: [Integer] -> Integer
sumNum [] = 0
sumNum (x:xs)
x < 10 = x + sumNum xs
otherwise = (x `mod` 10) + (x `div` 10) + sum xs
validate :: Integer -> Bool
validate n = (mod (sumNum (doubleRev (toDigits n))) 10) == 0
You forgot the guard bars:
sumNum (x:xs)
| x < 10 = ...
| otherwise = ...
Without the pipe characters, the compiler sees it as sumNum (x:xs) x < 10 = x + sumNum xs, which doesn't make sense as a pattern, since it seems to suggest you have 3 more arguments, namely x, < and 10, although < does not make sense as a name by itself. Alternatively you could just skip the guard altogether, since
> map (`mod` 10) [0..9] == [0..9]
True
> map (`div` 10) [0..9] == replicate 10 0
True
So all you save is a little efficiency. Since you're working with very small inputs you don't really need to worry about this, so you could just use sumNum [] = 0; sumNum (x:xs) = (x `mod` 10) + (x `div` 10) + sum xs, or more simply sumNum = sum . map (\x -> (x `mod` 10) + (x `div` 10)).

Haskell - eliminate prime numbers from a list

I want to write a function wp (without primes) which removes all the primes from a list
of numbers. Thus, wp [1, 2, 3, 4, 5, 6, 7] = [1, 4, 6].
I tried coding it like this:
wp :: [Int] -> [Int]
prime :: Int -> Bool
prime n = if f n > 0 then False else True
where f n = foldl (\acc x -> if n `mod` x == 0 then acc = acc + 1 else acc = acc + 0) 0 [2..n-1]
wp xs = filter (not.prime) xs
But when compiling it, I get the "parse error on input =" error but I can't find my syntax error. Any ideas?
Your problem is in the use of acc = acc + x. You just need to write it as acc + 1 or acc + 0 (or just acc really) instead. Also, I would recommend writing the function signature on top of the function definition, rather than a C-style list at the top.
Finally, I should note that wp will not include 1 in the result, so you will have to manually include it.
prime :: Int -> Bool
prime n = if f n > 0 then False else True
where f n = foldl (\acc x -> if n `mod` x == 0 then acc + 1 else acc) 0 [2..n-1]
wp :: [Int] -> [Int]
wp xs = 1 : filter (not.prime) xs

Adding two 8-Bit numbers in haskell

I was trying to define a function(s) that helped me simulate basic operations when using 8-Bit numbers.
I'm having a hard time figuring this one out.. I'm trying to keep it as simple as possible without importing anything, so I started with two lists of 8 elements in it (which are 0's and 1's).
If I'm not mistaken it should start looking like this:
bitsum :: [Int] -> [Int] -> [Int]
bitsum [][] = []
after this last line it starts to get kind of tricky for me because I can't add one to one the elements the lists.
bitsum (x:xs)(y:ys)
that's all that I have right now that I think is correct.
My idea was to try something like this:
bitsum :: [Int] -> [Int] -> [Int]
bitsum [][] = []
bitsum (x:xs)[] = (x:xs)
bitsum [](y:ys) = (y:ys)
bitsum (x:xs)(y:ys) | (x:xs) == (y:ys) && < 0 = (x:xs)
| (x:xs) == (y:ys) && > 0 =
but I think I'm taking a wrong turn somewhere.
I would really appreciate if someone could give me a hand with this problem.
You are going to need a carry bit. You can't add column by column. Let's do it piece by piece:
bitsum :: [Int] -> [Int] -> [Int]
bitsum = bitsum' 0
where
bitsum' _ [] [] = []
There's a start. We start with no carry, and we deal with the case of no more bits to add. So what if both bits are 0?
bitsum' 0 (0:xs) (0:ys) = 0 : bitsum' 0 xs ys
bitsum' 1 (0:xs) (0:ys) = 1 : bitsum' 0 xs ys
Okay, so if both are 0, and carry is 0, then the result for that bit is 0 and no carry. If there is a carry use it, and continue without one.
bitsum' 0 (1:xs) (1:ys) = 0 : bitsum' 1 xs ys
bitsum' 1 (1:xs) (1:ys) = 1 : bitsum' 1 xs ys
If they are one, its similar. except there will always be a carry. And then if they are different:
bitsum' 0 (x:xs) (y:ys) = 1 : bitsum' 0 xs ys
bitsum' 1 (x:xs) (y:ys) = 0 : bitsum' 1 xs ys
Well they have to be 0 and 1 because we've dealt with all other cases, so they must add up to one. You can figure out what it should be from that. You start to see some patterns above, and so this can all be condensed to end up with a shorter answer.
bitsum :: [Int] -> [Int] -> [Int]
bitsum = bitsum' 0
where
bitsum' _ [] [] = []
bitsum' carry (x:xs) (y:ys) | x == y = carry : bitsum' x xs ys
| otherwise = (1 - carry) : bitsum' carry xs ys
(1-carry) is a fancy way of flipping a 1 to 0 or vice versa since in that case the bit is always the opposite of the carry.
Carries are unnecessary for this. Note two properties of bitwise binary addition: the high digit is given by AND and the low digit is given by XOR. These are:
xor a b = if a == b then 0 else 1
and' 1 1 = 1 -- `and` is a function in Prelude.
and' _ _ = 0
To find the binary sum, simply take the bitwise xor and and to find the low and high digits, respectively. Shift the high digits (left or right, depending on Endian-ness) and take the sum of that, and the low digits.
Little endian:
bitsum0 :: [Int] -> [Int] -> [Int]
bitsum0 xs ys
| (sum xs) == 0 = ys
| (sum ys) == 0 = xs
| otherwise = bitsum0 low (0:high)
where low = zipWith xor xs ys
high = zipWith and' xs ys
Big endian:
bitsum1 :: [Int] -> [Int] -> [Int]
bitsum1 xs ys
| (sum xs) == 0 = ys
| (sum ys) == 0 = xs
| otherwise = bitsum1 low ((tail high) ++ [0])
where low = zipWith xor xs ys
high = zipWith and' xs ys
The two guards in each function ensure termination ; eventually, the recursion will end up adding x+0, which is when we are finished.
Note that no error checking is done. Overflows and lists of different lengths (as well as null lists) are undefined behaviour. Your lists could be filled full of meaningless garbage (particulary, and' treats 0 as 0 and everything else as 1). Perhaps it would be more pragmatic to use something like
data Bit = Bool
type Word_8 = (Bit , Bit , Bit , Bit , Bit , Bit , Bit , Bit )
or better yet
import Data.Word
binsum :: Word8 -> Word8 -> Word8
binsum = (+)
This is a super simple gate representation in Haskell.
Just began learning Haskell so the format is simple and how I'm learning..
Since building a bit sim in maths seemed fun, I hacked this together.. Hope it helps someone :)
andGate x y = [z | z <- [if (x == 1 && y == 1) then 1 else 0]]
orGate x y = [z | z <- [if (x == 1 || y == 1) then 1 else 0]]
nandGate x y = [z | q <- (andGate x y), z <- [if (q == 0) then 1 else 0 ]]
norGate x y = [z | q <- (orGate x y), z <- [if (q == 0) then 1 else 0 ]]
xorGate x y = [z |
xn <- [if (x == 0) then 1 else 0],
yn <- [if (y == 0) then 1 else 0],
q <- (andGate xn y),
p <- (andGate x yn),
z <- (orGate q p)]
xnorGate x y = [z |
xn <- [if (x == 0) then 1 else 0],
yn <- [if (y == 0) then 1 else 0],
q <- (andGate xn yn),
p <- (andGate x y),
z <- (orGate q p)]
halfAdder a b = [ (x, y) | x <- (xorGate a b), y <- (andGate a b)]
fullAdder a b c = [ (sum, cout) |
u1 <- xorGate a b,
u2 <- andGate a b,
sum <- xorGate u1 c,
u4 <- andGate u1 c,
cout <- orGate u4 u2]

Resources