isValid :: Position -> Bool
isValid Position(x _) = x
isValid Position(_ y) = y
| x 'elem' ['a'..'h'] && y 'elem' [1..8] = True
| otherwise = False
I keep getting this error error: Parse error in pattern: x
I am trying to write a function that tells me whether a given poisition is valid or not. Where x is ['a'..'h'] and y is [1..8]
As explained here: Syntax error on 'mod' Haskell
The syntax for using a named function as an infix operator uses backticks (grave accents, U+0060), not apostrophes:
| x `elem` ['a'..'h'] && y `elem` [1..8] = True
------ ------
| otherwise = False
In addition, Position(x _) and Position(_ y) are not valid patterns—you probably intended to use (Position x _) and (Position x y). Note the x, since x is not in scope in the equation you wrote for (Position _ y).
(Position x _) will match all positions, so I suspect you intended:
isValid :: Position -> Bool
isValid (Position x y)
| x `elem` ['a'..'h'] && y `elem` [1..8] = True
| otherwise = False
Or more simply:
isValid :: Position -> Bool
isValid (Position x y) = x `elem` ['a'..'h'] && y `elem` [1..8]
I keep getting this error error: Parse error in pattern: x I am trying to write a function that tells me whether a given position is valid or not. Where x is ['a'..'h'] and y is [1..8].
The other answers already discussed what is wrong: you used a guard in the clause where there is no bounded x:
isValid Position(_ y) = y
and furthermore you use quotes instead of backticks with the elem function:
x 'elem' ['a'..'h']
So a rigorous fix would be:
isValid :: Position -> Bool
isValid (Position x y)
| x `elem` ['a'..'h'] && y `elem` [1..8] = True
| otherwise = False
Since we actually return the result of the guard, we do not need to use guards and can collapse the guards into one expression:
isValid :: Position -> Bool
isValid (Position x y) = x `elem` ['a'..'h'] && y `elem` [1..8]
Nevertheless since we here work with ranges and the second range are integers, we do not have to use elem on a range, we can use:
isValid :: Position -> Bool
isValid (Position x y) = 'a' <= x && x <= 'h' && 1 <= y && y <= 8
For such small ranges, there will probably not be that much impact on performance, but elem works in O(n) worst case, whereas the two bounds checks work in O(1).
In
| x 'elem' ['a'..'h'] && y 'elem' [1..8] = True
x is unbound. It doesn't appear at all in
isValid Position(_ y) = y
in particular. Also, you probably meant to use `elem`, and not 'elem'.
I am trying to write a function that tells me whether a given poisition is valid or not. Where x is ['a'..'h'] and y is [1..8]
You didn't write the definition of Position, but it seems like this would be something like
data Position = Position Int Int
isValid :: Position -> Bool
isValid (Position x y) = x `elem` ['a'..'h'] && y `elem` [1..8]
(which builds for me).
Related
Basically i have this code
ola xs = foldl (\acc x -> if (chr x >= 65 && chr x <= 71 || chr x >= 97 && chr x <= 103) then acc (++) x) [] xs
And when i try to load it on ghci it says i have a parse error in the last parenthesys so can you help me? What is wrong here?
You are finding all occurrecne of letters A to G in a string in case in sensitive manner. As said in comments you are missing the else case. The else case should simply be returning the acc variable.
But still there are mistakes in your program. The function chr takes a number and returns ascii character. What you need is ord, which takes char and returns ascii value.
So the version of your program will be
ola xs = foldl (\acc x -> if (ord x >= 65 && ord x <= 71 || ord x >= 97 && ord x <= 103) then acc ++ [x] else acc) [] xs
Char data type is already of the Ord class, so you can compare them. No need for using ord. With this you can write above as
ola xs = foldl (\acc x -> if (x >= 'A' && x <= 'G' || x >= 'a' && x <= 'g') then acc ++ [x] else acc) [] xs
There is special function in list known as filter which takes from a list only the needed elements. Using filter the above program will be.
ola xs = filter (\x -> x >= 'A' && x <= 'G' || x >= 'a' && x <= 'g') xs
now the argument can simply be removed and it can be simply written as
ola = filter (\x -> x >= 'A' && x <= 'G' || x >= 'a' && x <= 'g')
Bonus :-
But now what if you have some random character you want to check. You can first create a string for the characters you want to filter. For the above example this will suffice.
strList=['A'..'G','a'..'g'];
Now filter using elem. elem checks if a given element is present in string.
ola xs = filter (\x -> elem x strList) xs
Bonus 2:-
What if you want to remove the arguments xs. For that first you need to first flip the arguments of the elem, so that the list will be first.
ola = filter ((flip elem) strList)
i recently picked up Haskell and i am having trouble putting in code the way to look if an element is in the rest of the list (x:lx) in this case in lx.
My code:
atmostonce:: [Int] -> Int -> Bool
atmostonce [] y = True
atmostonce (x:lx) y
| (x==y) && (`lx` == y) = False
| otherwise = True
The way it is now checks for the first element (x==y) but i don't know how to check if the element y exists in lx. The thing i am actually trying to accomplish is to find out if in the list of Intigers lx the number y contains 0 or 1 times and return True otherwise return False
There are several implementations you could use for this, one that I see which avoids applying length to a potentially infinite list is
atmostonce xs y
= (<= 1)
$ length
$ take 2
$ filter (== y) xs
This removes all elements from xs that are not equal to y, then takes at most 2 of those (take 2 [1] == [1], take 2 [] == []), calculates the length (it's safe to use here because we know take 2 won't return an infinite list), then checks if that is no more than 1. Alternatively you could solve this using direct recursion, but it would be best to use the worker pattern:
atmostonce = go 0
where
go 2 _ _ = False
go n [] _ = n <= 1
go n (x:xs) y =
if x == y
then go (n + 1) xs y
else go n xs y
The n <= 1 clause could be replaced by True, but ideally it'll short-circuit once n == 2, and n shouldn't ever be anything other than 0, 1, or 2. However, for your implementation I believe you are looking for the elem function:
elem :: Eq a => a -> [a] -> Bool
atmostonce [] y = True
atmostonce (x:ls) y
| (x == y) && (y `elem` ls) = False
| otherwise = True
But this won't return you the value you want, since atmostonce [1, 2, 2, 2] 2 would return True. Instead, you'd need to do recursion down the rest of the list if x /= y:
atmostonce (x:ls) y
| (x == y) && (y `elem` ls) = False
| otherwise = atmostonce ls y
You can do this using the elem function:
atmostonce:: [Int] -> Int -> Bool
atmostonce [] y = True
atmostonce (x:lx) y | x /= y = atmostonce lx y
| otherwise = not $ elem y lx
You better first check if the element x is not equal to y. If that is the case, you simply call the recursive part atmostonce lx y: you thus search further in the list.
In case x == y, (the otherwise case), you need to check if there is another element in lx (the remainder of the list), that is equal to x. If that is the case, you need to return False, because in that case there are multiple instances in the list. Otherwise you return True.
Furthermore you can generalize your function further:
atmostonce:: (Eq a) => [a] -> a -> Bool
atmostonce [] y = True
atmostonce (x:lx) y | x /= y = atmostonce lx y
| otherwise = not $ elem y lx
Eq is a typeclass, it means that there are functions == and /= defined on a. So you can call them, regardless of the real type of a (Int, String, whatever).
Finally in the first case, you can use an underscore (_) which means you don't care about the value (although in this case it doesn't matter). You can perhaps change the order of the cases, since they are disjunct, and this makes the function syntactically total:
atmostonce:: (Eq a) => [a] -> a -> Bool
atmostonce (x:lx) y | x /= y = atmostonce lx y
| otherwise = not $ elem y lx
atmostonce _ _ = True
The existing answers are good, but you can use dropWhile to do the part that's currently done via manual recursion:
atMostOnce xs y =
let afterFirstY = drop 1 $ dropWhile (/= y) xs
in y `notElem` afterFirstY
I'm writing a function like this:
testing :: [Int] -> [Int] -> [Int]
testing lst1 lst2 =
let t = [ r | (x,y) <- zip lst1 lst2, let r = if y == 0 && x == 2 then 2 else y ]
let t1 = [ w | (u,v) <- zip t (tail t), let w = if (u == 2) && (v == 0) then 2 else v]
head t : t1
What the first let does is: return a list like this: [2,0,0,0,1,0], from the second let and the following line, I want the output to be like this: [2,2,2,2,1,0]. But, it's not working and giving parse error!!
What am I doing wrong?
There are two kinds of lets: the "let/in" kind, which can appear anywhere an expression can, and the "let with no in" kind, which must appear in a comprehension or do block. Since your function definition isn't in either, its let's must use an in, for example:
testing :: [Int] -> [Int] -> [Int]
testing lst1 lst2 =
let t = [ r | (x,y) <- zip lst1 lst2, let r = if y == 0 && x == 2 then 2 else y ] in
let t1 = [ w | (u,v) <- zip t (tail t), let w = if (x == 2) && (y == 0) then 2 else y] in
return (head t : t1)
Alternately, since you can define multiple things in each let, you could consider:
testing :: [Int] -> [Int] -> [Int]
testing lst1 lst2 =
let t = [ r | (x,y) <- zip lst1 lst2, let r = if y == 0 && x == 2 then 2 else y ]
t1 = [ w | (u,v) <- zip t (tail t), let w = if (x == 2) && (y == 0) then 2 else y]
in return (head t : t1)
The code has other problems, but this should get you to the point where it parses, at least.
With an expression formed by a let-binding, you generally need
let bindings
in
expressions
(there are exceptions when monads are involved).
So, your code can be rewritten as follows (with simplification of r and w, which were not really necessary):
testing :: [Int] -> [Int] -> [Int]
testing lst1 lst2 =
let t = [ if y == 0 && x == 2 then 2 else y | (x,y) <- zip lst1 lst2]
t1 = [ if (v == 0) && (u == 2) then 2 else v | (u,v) <- zip t (tail t)]
in
head t : t1
(Note, I also switched u and v so that t1 and t has similar forms.
Now given a list like [2,0,0,0,1,0], it appears that your code is trying to replace 0 with 2 if the previous element is 2 (from the pattern of your code), so that eventually, the desired output is [2,2,2,2,1,0].
To achieve this, it is not enough to use two list comprehensions or any fixed number of comprehensions. You need to somehow apply this process recursively (again and again). So instead of only doing 2 steps, we can write out one step, (and apply it repeatedly). Taking your t1 = ... line, the one step function can be:
testing' lst =
let
t1 = [ if (u == 2) && (v == 0) then 2 else v | (u,v) <- zip lst (tail lst)]
in
head lst : t1
Now this gives:
*Main> testing' [2,0,0,0,1,0]
[2,2,0,0,1,0]
, as expected.
The rest of the job is to apply testing' as many times as necessary. Here applying it (length lst) times should suffice. So, we can first write a helper function to apply another function n times on a parameter, as follows:
apply_n 0 f x = x
apply_n n f x = f $ apply_n (n - 1) f x
This gives you what you expected:
*Main> apply_n (length [2,0,0,0,1,0]) testing' [2,0,0,0,1,0]
[2,2,2,2,1,0]
Of course, you can wrap the above in one function like:
testing'' lst = apply_n (length lst) testing' lst
and in the end:
*Main> testing'' [2,0,0,0,1,0]
[2,2,2,2,1,0]
NOTE: this is not the only way to do the filling, see the fill2 function in my answer to another question for an example of achieving the same thing using a finite state machine.
t = True
f = False
anzNachbarn :: [[Bool]] -> (Integer,Integer) -> Integer
anzNachbarn a (x,y)
| x < 0 || y < 0=-1
| otherwise ... here comes the comparison
This is an example matrix:
[[True,False,False],
[True,False,False],
[False,True,False]]
here i need an algorithm, where it calculates (for given x and y position in matrix) its neighbours (only "true" neighboors) and increase it by 1 for each true neighboor.
For example: anzNachbarn [[True,False,False],[True,False,False],[False,True,False]] (0,1)
returns 2 back.
:Edit
I still have a question how can I now implement each component of the result matrix, the number of named elements with True neighboring fields indicates the corresponding component of the argument matrix Applies to
[[True, False, False],
[True, False, False],
[False, True , False]]
the function func returns the results matrix [[1,2,0], [2,3,1], [2,1,1]]
with signature func :: [[Bool]] -> [[Integer]]
have you got any idea about this ?
You almost certainly want to use an array (from Data.Array) in this situation, since looking up an item in a list by its index is very slow.
Here's a quick implementation using Array:
countNeighbors :: Array (Int, Int) Bool -> (Int, Int) -> Int
countNeighbors board (x, y) = length
[ (x', y')
| x' <- [x - 1, x, x + 1]
, y' <- [y - 1, y, y + 1]
, x' /= x || y' /= y
, inRange (bounds board) (x', y')
, board ! (x', y')
]
This is a list comprehension with two generators and three guards. The generators simply give us the indices of the nine positions in a three-by-three square centered at (x, y) (you'll need a minor change if you don't want neighbors at the corners to be considered).
The first guard (x' /= y') ignores (x, y) itself. The second throws out positions that aren't within the bounds of the array. The final guard throws out positions that are in the array but have a False value.
So we now have a list of indices for the neighbors with True values. The length of this list is the desired count.
This is ugly, but seems to work...
anzNachbarn :: [[Bool]] -> (Int,Int) → Integer
anzNachbarn a (x,y)
| x < 0 || y < 0 = -1
| otherwise = sum [v x' y' | x' <- [max 0 (x-1)..x+1],
y' <- [max 0 (y-1)..y+1],
x ≠ x' || y ≠ y' ]
where v i j = if j >= length a
|| i >= length (a !! 0)
|| not (a !! j !! i)
then 0 else 1
[Edit]
In order to convert the whole array, you can write the equally ugly
conv a = [line y | y <- [0 .. (length a) - 1]]
where line y = [anzNachbarn a (x,y) | x <- [0 .. ((length (a !! 0) - 1)]]
Note that the performance of this is terrible.
I am doing problem 112 on Project Euler and came up with the following to test the example case (I'll change the number in answer to 0.99 to get the real answer):
isIncre x | x == 99 = False
| otherwise = isIncre' x
where
isIncre' x = ???
isDecre x = isIncre (read $ reverse $ show x :: Int)
isBouncy x = (isIncre x == False) && (isDecre x == False)
bouncers x = length [n|n<-[1..x],isBouncy n]
nonBouncers x = length [n|n<-[1..x],(isBouncy n) == False]
answer = head [x|x<-[1..],((bouncers x) / (nonBouncers x)) == 0.5]
But what I don't know how to do is define a function isIncre' which tests to see if the digits in a number are greater than or equal to the one on their left. I know it needs to be done recursively but how?
On a side note, I know I can only use / on two floating point numbers but how can I make the output of bouncers to be floating point number instead of an integer?
Edit:
Thanks for the help, but it didn't like the = when I changed isIncre to:
isIncre x | x <= 99 = False
| otherwise = isIncre' (mshow x)
where
isIncre' (x:y:xs) = (x <= y) && (isIncre' (y:xs))
isIncre' _ = True
The number 0.99 cannot be represented exactly in base 2. Hence you may want to avoid the use of floating point numbers for this assignment. Instead, to see whether exactly 99% of the numbers <= x are bouncers, test whether
100 * (x - bouncers x) == x
This works because it is (mathematically) the same as (x - bouncers x) == x / 100, which is true if (x - bouncers x) (the number of non-bouncy numbers) is 1% of x. Observe that there is thus no need to define nonBouncers.
Also, another way to define bouncers is
bouncers x = length $ filter isBouncy [1..x]
However, you should reconsider your design. Currently you are recalculating the number of bouncy numbers up to x, for every x that you try. So a lot of work is being done over and over. What you may instead want to do, is generate a sequence of tuples (x, n), where n is the number of bouncy numbers <= x. Observe that if there are n bouncy numbers <= x, then there are either n or n + 1 bouncy number <= x + 1.
More specifically, to calculate (x + 1, n'), all you need is (x, n) and the output of isbouncy (x + 1).
If you have a string representation of an integer number, you could write the isIncre function like this (ord converts a character to an integer and string is just a list of chars):
isIncre (x:y:xs) = ord x <= ord y && isIncre (y:xs)
isIncre _ = True
It could be even nicer to write the isIncre function without ord, working on any ordered type, then combine it with "map ord" when you call it instead. The implementation would then be just:
isIncre (x:y:xs) = x <= y && isIncre (y:xs)
isIncre _ = True
That could be called like this, if x is an integer number
isIncre (map ord (show x))
I would use really nice functional version of isIncre if you have string representation of intetger.
isIncre :: (Ord a) => [a] -> Bool
isIncre list = and $ zipWith (<=) list (tail list)
If not, just compose it with show.
isIncreNum :: Integer -> Bool
isIncreNum = isIncre . show