I am fairly new to Haskell and am working on an assignment simulating checkers currently. I am having a bit of difficulty determining the proper method of conditionally checking an expression and updating the values of a tuple. I have a function called getPos that will return the Char at a specific location on the board to determine its state.
onemove :: (Int,[Char],[[Char]],(Int,Int)) -> (Int,[Char],[[Char]])
onemove (a,b,c,(d,e))
| e <= 0 =(a-30,b,c)
| e > 50 =(a-30,b,c)
| (((posTo == 'r') || (posTo == 'i')) &&((posFrom == 'w')||(posFrom == 'k'))) == 'true' =(a-20,b,c)
| (((posTo == 'w')||(posTo == 'k')) && ((posFrom == 'r') || (posFrom == 'i')))== 'true' =(a-20,b,c)
| otherwise = (1000,b,c)
where posFrom = getPos (d, c)
posTo = getPos (e,c)
Is it correct to use a function to define a variable within my where clause? I receive the following error on my last line:
parse error on input `='
Your immediate problem is mostly just caused by indentation. Guards need to be indented w.r.t the definition they're associated with.
onemove :: (Int,[Char],[[Char]],(Int,Int)) -> (Int,[Char],[[Char]])
onemove (a,b,c,(d,e))
| e <= 0 =(a-30,b,c)
| e > 50 =(a-30,b,c)
| (((posTo == 'r') || (posTo == 'i')) &&((posFrom == 'w')||(posFrom == 'k'))) =(a-20,b,c)
| (((posTo == 'w')||(posTo == 'k')) && ((posFrom == 'r') || (posFrom == 'i'))) =(a-20,b,c)
| otherwise = (1000,b,c)
where posFrom = getPos (d, c)
posTo = getPos (e,c)
Notice I also removed the == 'true' in your original code. That was wrong for three separate reasons.
Single quotes denote a Char. Double quotes for String.
You can't compare a Boolean value to a String just because that String
happens to say "true". You would have to say == True.
There's no reason to ever write bool == True, because that's
exactly the same as just writing bool.
Also, a, b, c, and (d,e) should probably all be separate arguments, not a single tuple. You lose all the advantages of currying that way.
Related
This function should take two arguments a list and an int. if an element of the list and the number “a” parity is equal then they’d have to be summed, else the two numbers should be subtracted.
The calculation should be done in this order :
At the beginning, the residual value r is the value of a,
Each element e of lst (taken in the order given by the list) affects the residual value: if e and r are of the same parity (both odd or both even) then the new r’ is equal to the sum of r + e, if not then it should be equal to the subtraction of r - e,
The last r is the result expected.
To put this into an example:
par [4;7;3;6] 5
should return -1, it would work as follows :
5 and 4 have a different parity so we subtract -> 5 - 4 = 1
1 and 7 are both odd, so we add them together -> 1 + 7 = 8
8 and 3 have a different parity -> 8 - 3 = 5
Finally, 5 and 6 have different parity -> 5 - 6 = -1
I have thought of something like this below :
let rec par lst a =
match lst with
| [] -> 0
| h::t -> if (h mod 2 == 0 && a mod 2 == 0) || (h mod 2 == 1 && a mod 2 == 1) then a + h
| h::t -> if (h mod 2 == 0 && a mod 2 == 1) || (h mod 2 == 1 && a mod 2 == 0) then a - h :: par t a ;;
EDIT1 : Here is the error I get from the compiler :
Line 4, characters 83-88: Error: This expression has type int but an
expression was expected of type unit because it is in the result of a
conditional with no else branch
The idea is to build this function using no more than the following predefined functions List.hd, List.tl et List.length.
What is disturbing in my proposition above and how to remediate it? Anyone can help me resolve this, please?
EDIT 2:
I was able to do what is needed with if...then... else syntax (not the best I know for OCaml) but I personally have more difficulties sometimes understanding the pattern matching. Anyhow here's what I got :
let rec par lst a = (* Sorry it might hurt some sensible eyes *)
if List.length lst = 0 then a
else
let r = if (List.hd lst + a) mod 2 == 0 then (a + (List.hd lst))
else (a - (List.hd lst)) in
par (List.tl lst) r ;;
val par : int list -> int -> int = <fun>
Suggestions and help to put it into a pattern-matching syntax are welcomed.
Your code doesn't compile. Did you try compiling it? Did you read the errors and warnings produced by the compiler? Could you please add them to your question?
A few comments about your code:
| h::t -> if ... then ... should be | h::t when ... -> ...;
(h mod 2 == 0 && a mod 2 == 0) || (h mod 2 == 1 && a mod 2 == 1) can be simplified to (h - a) mod 2 == 0;
The compiler likes to know that the matching was exhaustive; in particular, you don't need to repeat the test in the third line of the matching (the third line will only be read if the test was false in the second line);
You are missing the recursive call in the second line of the matching;
In the third line of the matching, you are returning a list rather than a number (the compiler should have explicitly told you about that type mismatch!! did you not read the compiler error message?);
In the first line of the matching, in case the list is empty, you return 0. Are you sure that 0 is the value you want to return, when you've reached the end of the list? What about the residual value that you have calculated?
Once you have fixed this version of your code as a recursive function, I recommend trying to write a code solving the same problem using List.fold_left, rather than List.hd and List.tl as you are suggesting.
When I first wrote my answer, I included a fixed version of your code, but I think I'd be doing you a disservice by handing out the solution rather than letting you figure it out.
I seem to be stuck on a question and have no idea how to approach it or what Im doing wrong with my current code.
I have to write a function called oddDigits which takes a single integer argument and returns a boolean result. It should return True if and only if the argument is a positive integer with an odd number of digits. If the argument is zero or negative, the function should stop with an error message.
Also, cant convert the argument into a string. Have to use recursion.
I have a feeling each digit could be stored in a list recursively and then the length of the list could determine the answer.
So far, I have this:
oddDigits :: Integer -> Bool
lst = []
oddDigits x
| (x < 0) || (x == 0) = error
| x `mod` 10 ++ lst ++ oddDigits(x `div` 10)
| length(lst) `mod` 2 /= 0 = True
| otherwise = False
Sorry if the code looks horrible. I am new to Haskell and still learning. What exactly am I doing wrong and how could I correct it?
First off, this seems a pretty weird thing to check. Perhaps what you're doing wrong is to ever consider this problem...
But if you persist you want to know the property of an integer having an odd number of digits... oh well. There's a lot that could be improved. For starters, (x < 0) || (x == 0) doesn't need the parentheses – < and == (infix 4) bind more tightly than ||. If you're not sure about this, you can always ask GHCi:
Prelude> :i ==
class Eq a where
(==) :: a -> a -> Bool
...
-- Defined in ‘GHC.Classes’
infix 4 ==
Prelude> :i ||
(||) :: Bool -> Bool -> Bool -- Defined in ‘GHC.Classes’
infixr 2 ||
But here you don't need || anyway because there's a dedicated operator for less-than-or-equal. Hence you can just write
oddDigits x
| x <= 0 = error "bla bla"
| ...
Then, you can “convert” the number to a string. Converting to string is generally a really frowned-upon thing to do because it throws all structure, typechecking etc. out of the window; however “number of digits” basically is a property of a string (the decimal expansion), rather than a number itself, so this is not entirely unsensible for this specific task. This would work:
oddDigits x
| x <= 0 = error "blearg"
| length (show x)`mod`2 /= 0 = True
| otherwise = False
however it's a bit redundancy department redundant. You're checking if something is True, then give True as the result... why not just put it in one clause:
oddDigits x
| x <= 0 = error "blearg"
| otherwise = length (show x)`mod`2 /= 0
That's perhaps in fact the best implementation.
For any proper, sensible task, I would not recommend going the string route. Recursion is better. Here's what it could look like:
oddDigits 1 = True
oddDigits x
| x <= 0 = error "blearg"
| otherwise = not . oddDigits $ x`div`10
There's nothing wrong with your general approach of converting to a list of digits, then finding the length of the list. Really where you went wrong is trying to cram everything into one function. As you found out first hand, it makes it very difficult to debug. Functional programming works best with very small functions.
If you separate out the responsibility of converting an integer to a list of digits, using a digs function like the one from this answer, the rest of your algorithm simplifies to:
oddDigits x | x <= 0 = error
oddDigits x = odd . length $ digs x
leftaroundabout's eventual answer is very nice, however it fails for numbers like 2,3 and 23. Here's a fix.
oddDigits x
| x <= 0 = error "blearg"
| x < 10 = True
| otherwise = not . oddDigits $ x`div`10
Its much more elegant than my initial answer, below. I'm including it to introduce a common functional paradigm, a worker/wrapper transformation of the problem. Here the wrapper gives the interface and passes off the work to another function. Notice that the negativity check only needs to be done once now.
oddDigits :: Integer -> Bool
oddDigits x
| x <= 0 = False
| otherwise = oddDigits' True x
oddDigits' :: Bool -> Integer -> Bool
oddDigits' t x
| x < 10 = t
| otherwise = oddDigits' (not t) $ x `div` 10
oddDigits' carries a piece of internal data with it, the initial Bool. My first first thought was to have that Bool be a digit accumulator, counting the number of digits. In that case, an "unwrapper" needs to be supplied, in this case the standard "odd" function:
oddDigits x
| x <= 0 = False
| otherwise = odd . oddDigits'' 1 $ x
where oddDigits'' :: Integer -> Integer -> Integer.
I have a problem, can you help me.
var query = (from MONHOC in db.tbl_MONHOCs
where
(MONHOC.IS_DELETE != 1 ||
MONHOC.IS_DELETE == null) &&
MONHOC.ISBATBUOC == 1
select new
{
ID = ("MH_CHA_" + Convert.ToString(MONHOC.ID_MONHOC)),
ID_NAME = MONHOC.ID_MONHOC,
MA_MONHOC = MONHOC.MA_MONHOC,
NAME = MONHOC.TEN_MONHOC,
ID_PARENT = 0
}).Concat
(from MONHOC in db.tbl_MONHOCs
where
(MONHOC.IS_DELETE != 1 ||
MONHOC.IS_DELETE == null) &&
MONHOC.ISBATBUOC == 0
select new
{
ID = ("MH_CON_" + Convert.ToString(MONHOC.ID_MONHOC)),
ID_NAME = MONHOC.ID_MONHOC,
MA_MONHOC = MONHOC.MA_MONHOC,
NAME = MONHOC.TEN_MONHOC,
ID_PARENT = (int?) MONHOC.ID_MONHOC_CHA
}
);
Error
Error Compiling Expression: Error Compiling Expression:
'System.Linq.IQueryable' does not contain a
definition for 'Concat' and the best extension method overload
'System.Linq.ParallelEnumerable.Concat(System.Linq.ParallelQuery,
System.Collections.Generic.IEnumerable)' has some invalid
arguments Instance argument: cannot convert from
'System.Linq.IQueryable' to
'System.Linq.ParallelQuery'
The exception message "clearly" :) tells you that the types of the properties in the anonymous types don't match.
In the first part you have:
ID_PARENT = 0
In the second part:
ID_PARENT = (int?) MONHOC.ID_MONHOC_CHA
These properties should both either be int? or int.
Without thinking in C# I tried to compare three objects. It failed, and explained why [since (typeof("A == B") == bool) and (typeof(C) != bool) it was an invalid comparison]. Do any languages support short circuiting logic like this?
There are several languages that let you do multiple conditionals like this.
But the first I could think of was Python
Example:
a = 5
b = 5
c = 5
if(a == b == c):
print "yes"
else:
print "no"
Will print "yes" in the console.
It works with other types as well, like this:
a = ["A",1]
b = ["A",1]
c = ["A",1]
d = ["A",1]
if(a == b == c == d):
print "YES"
else:
print "NO"
Now the reason for C# (And other C like languages) doesn't support this is that they evaluate comparison expressions down to a true / false, so what your compiler sees when you do (5 == 5 == 5) is ((5 == 5) == 5) which yields: (true == 5) which invalid since you cannot compare a Boolean to an integer, you could actually write (a == b == c) if c is a Boolean, so (5 == 5 == true) would work.
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.