I am new to Haskell and trying few things. I have a small program.
module Collatz where
compute_collatz :: Integer -> Integer
compute_collatz x = if even x then evenComputation else oddcomputation
where evenComputation = div x 2
oddcomputation = 3 * x + 1
compute_steps :: Integer -> Integer
compute_steps 1 = 0
compute_steps num = 1 + compute_steps(compute_collatz(num))
I wanted to print the sequence of numbers generated by each compute_collatz(num) call. How can I add a print or show statement in either compute_steps or compute_collatz functions
This is not a good approach.
A better alternative is to make the result of the function a list of visited numbers, instead of just the final one.
collatzSeq :: Integer -> [Integer]
collatzSeq 1 = [1]
collatzSeq x
| even x = x : collatzSeq (x`div`2)
| otherwise = x : collatzSeq (3*x + 1)
Then you can use this list for counting steps, printing, whatever. Note that thanks to lazyness you need need to worry that the whole list would need to be computed before the printing starts – it'll just print as you go in the computation.
So I'm new to Haskell, and I've been trying to implement the function which finds the smallest coprime number. I have another function for calculating GCD.
I've already tried various ways to implement my function, however, they all failed.
smallestCoPrimeOf :: Int -> Int
smallestCoPrimeOf a
| gcd a b == 1 = b
| otherwise = gcd a (b+1)
OR replacing the last two lines with
b = 2
if (gcd a b) == 1
then b
else gcd a (b+1)
OR
let b = 2
if (gcd a b) == 1 then b else gcd a (b+1)
And all of these end up throwing errors like "parse error on input ‘|’", or "parse error on input ‘if’". Every time I google something and try correcting the mistake, the same error repeats/ anothe one appears. Where is my mistake?
In Haskell, indentation matters. You must indent the lines to show what lines are subordinate to others. This is what allows Haskell to avoid using so many brackets, like other languages. Like so:
smallestCoPrimeOf :: Int -> Int
smallestCoPrimeOf a
| gcd a b == 1 = b
| otherwise = gcd a (b+1)
The amount of indentation is not perscribed, as long as it is consistent.
You could also write:
smallestCoPrimeOf :: Int -> Int
smallestCoPrimeOf a =
let b = 2
in if (gcd a b) == 1
then b
else gcd a (b+1)
Notice how let and in align, as well as if-then-else.
If you're using GHCi, remember to put multi-line declarations in :{-:}:
λ> :{
λ| smallestCoPrimeOf a
λ| | gcd a b == 1 = b
λ| | otherwise = gcd a (b+1)
λ| :}
There are other issues with your code, but these are for you to discover.
i just learned haskell yesterday and i'm stuck with a task.
i have a Matrix given; implemented with a function like this:
board 1 1 = 0
board 1 2 = 1
board 1 3 = 0
board 2 1 = 2
board 2 2 = 0
board 2 3 = 0
board 3 1 = 1
board 3 2 = 0
board 3 3 = 2
board _ _ = -1
Just that you have a little context:
that matrix is used for a minified sinking ships game.
so you would check an entry 2 1 like this
board 2 1
and get the respective result.
0 is a default value, -1 doesnt exist; 1 stands for a ship owned by player 1, the same goes with 2.
Now i have to write a function that just has to count the amount of ships owned by a specific player and it should return that amount.
e.g in that example board, the amount of 2's would be 2.
However, i have a restriction that i cant use anything related to lists.
I guess i have to work with recursion, and this is where i'm stuck.
i already have made a try with this:
(k is the player number and res should be the result.)
amountofships k board = rekurs 1 1 board res
where
res = 0
rekurs x y board res =
if (board x y == -1) then return(res)
else return(rekurs (x + 1) 1 board res)
where
new_rekurs a b board res2 =
if (board a b == -1) then return(res2)
else if (board a b == k) then return(new_rekurs a (b+1) board (res + 1))
else return(new_rekurs a (b+1) board res)
where
res2 = 0
Its meant to have a resursion function that goes through every column and inside that, it has another recursion function that would check every entry inside that column, return the amount, then check the next column, etc.
it doesnt compile and i dont think its an elegant approach, but I cant think of another one.
I would be thankful for any kind of help.
Edit : Thank you all for your answers. I see where the problem in my Code was.
I've used the structure proposed by Daniel, and it compiles at least:
amountofships k board = rekursColumn 1 1 0
where
rekursColumn x y res
| board x y = res
| otherwise = rekursColumn (x + 1) y (res + rowTotal)
where
rowTotal = rekursRow x y 0
rekursRow x y res
| board x y = res
| otherwise = rekursRow x (y + 1) (res + isOurBoat)
where
isOurBoat = if board x y == k then 1 else 0
I still get an Could not deduce (Num Bool) arising from the literal ‘1’
Error when calling
amountofships 1 example_board
. I guess this is because i didnt specify what the input types are? Specially since one parameter is actually a function.
Edit2: Oh i see where the problem was. I need to check if board x y == -1
my Code is working now:
amountofships :: Int -> (Int -> Int -> Int) -> Int
amountofships k board = rekursColumn 1 1 0
where
rekursColumn x y res
| board x y == -1 = res
| otherwise = rekursColumn (x + 1) y (res + rowTotal)
where
rowTotal = rekursRow x y 0
rekursRow x y res
| board x y == -1 = res
| otherwise = rekursRow x (y + 1) (res + isOurBoat)
where
isOurBoat = if board x y == k then 1 else 0
Thank you all for your help!
Okay, yes, you're a bit confused.
So my advice first is to try to straighten out what you want to do, in mostly English. I'm going to try to lead you to that without outright giving you the answer, since the point of this exercise is for you to learn more Haskell.
So it seems to me - though you haven't explained it - that what you intend to happen is:
amountofships calls internal function rekurs telling it to start at position 1 1 and passing it an accumulator argument that should start at 0
rekurs should examine the spot it's given, and if that spot is -1 say "oh, I'm off the grid, return the accumulator argument", and otherwise it should return the result of calling itself with one spot to the right.
Then you also somewhere define something called new_rekurs that you don't ever call.
So first let's try to fix your logic first, and then if you still have trouble translating that into Haskell we can work on that.
So the general pattern that you seem to be following is "call an internal tail-recursive function with an accumulator argument that checks "am I done yet?" and, if done, returns the accumulator argument. If not done, it computes the next place it should go and then calls itself on that."
Now, that's an okay pattern to use to solve this, but there are two problems with what you're doing:
You never add anything to the accumulator.
You need to travel in two dimensions.
So, traveling in two dimensions: there are two ways to do it. One is to keep a single function that keeps increasing x with each step until it gets to -1 and then increases y by 1 and reset x to 1. Another way - which I think in your case will be much, much easier - is to have two functions called rekursBoard and rekursRow (or whatever names you prefer) and the first function calls the second one to get the number of relevant ships in each row.
With the two-function solution, what you'd want to do is:
At the top level, call rekursBoard 1 1 0 (the arguments there are x, y, and res - note that you don't need to keep passing the board function on down to the inner functions)
In rekursBoard check if the given spot is off the board. If it is, the result is just res. If not, then the result is rekursBoard (x+1) y (res+rowTotal), where rowTotal is computed by calling rekursRow x y 0.
In rekursRow, check if the given spot is off the board. If it is, the result is just res. Otherwise, the result is rekursRow x (y+1) (res+isOurBoat), where isOurBoat is computed as 1 if the boat at spot x and y matches the k the top-level function was given, and 0 if not.
The overall structure of your function could look like this:
amountofships k board = -- .... some call here
where
rekursBoard x y res = -- ... some stuff here
where
rowTotal = -- ... some call here
rekursRow x y res = -- ... some stuff here
where
isOurBoat = -- ... something here
This isn't the only way to structure it, of course, it's just what I would do if I were writing up the answer sheet to this problem. Another very viable way to structure it is to make rekursRow something that's defined inside the where clause of rekursBoard and doesn't an x argument.
Now, a word in general on working in Haskell - Haskell has a function called return that means almost nothing like you expect. Seriously, at this early stage of learning Haskell, don't use return unless you're copying boilerplate code from the book. return DOES NOT DO WHAT YOU EXPECT. I personally think that the function is poorly named and that modern Haskell courses should avoid ever putting return on the page and instead use pure every place where they use return. (since on modern Haskell compilers, return and pure are the same thing for all the standard Monads)
Therefore, if you put return in your Haskell code for this problem, you will be sorry.
Don't do it.
Instead, get used to writing code like this:
countEmptySquare x y board = if board x y == 0 then 1 else 0
That is, just the form if someExpression then onePossibility else otherPossibility. No return statement, just bare expressions.
This will seem tedious at first, breaking down each calculation into named pieces, but it gets better. However, for laying out what's going on at an early level you should work through the careful break down.
First let me clean up that code of yours, syntactically:
amountofships :: ... -- Always write out type signatures!
amountofships k board = rekurs 1 1 board res
where res = 0
rekurs x y board res
| board x y == -1 = return res -- guards usually read nicer than `if`
| otherwise = return $ rekurs (x + 1) 1 board res
where new_rekurs a b board res2
| board a b == -1 = return res2 -- no need for parens around function arguments!
| board a b == k = return $ new_rekurs a (b+1) board (res + 1)
| otherwise = return $ new_rekurs a (b+1) board res
where res2 = 0
Now, a big problem here is return. Note that return in Haskell is very different from return in most other languages. It is not a keyword that's generally needed for the result of functions, instead, return is itself just a library function:
return :: Monad m => a -> m a
You need this to inject a value of “pure type” a, for example 3 :: Int, into the result of a monadic action of type m a, e.g. Just 3 :: Maybe Int. For example, you might use it thus:
-- Find the first even number in the tuple, if any
fstEven :: (Int, Int) -> Maybe Int
fstEven (a,b)
| even a = return a -- for the `Maybe` monad, this is the
| even b = return b -- same as writing `Just a` / `Just b`.
| otherwise = Nothing
Observe that I didn't write return Nothing: that would wrap the already monadic, empty value Nothing :: Maybe Int into another monadic layer, which is too much monad here.
Similar in your code: you wrap every result in return, but never unwrap anything.
Since in your case, everything is “pure” anyway, there's simply no need for that. To make something the result of a function, just write it out, like:
-- Use the first number in the tuple, if it's even; else use the second.
fstIfEven :: (Int, Int) -> Int
fstIfEven (a,b)
| even a = a
| otherwise = b
Or, in your case,
amountofships :: ... -- Always write out type signatures!
amountofships k board = rekurs 1 1 board res
where res = 0
rekurs x y board res
| board x y == -1 = res
| otherwise = rekurs (x + 1) 1 board res
where new_rekurs a b board res2
| board a b == -1 = res2
| board a b == k = new_rekurs a (b+1) board (res + 1)
| otherwise = new_rekurs a (b+1) board res
where res2 = 0
That looks better, but it doesn't work – here comes the interesting problem. See, you seem to not really think of recursion here. For a “recursive loop” in Haskell, you don't initialise a variable with something like res = 0 and then somehow change it in the course of the loop. Rather you straight up call the loop-body function with the initial value as the “front-end argument”, and then keep the function calling itself with other arguments. I'll demonstrate it for the simplified problem with only one grid-dimension. Instead of these magic numbers, I shall use descriptive tag types:
data Player = PlayerA | PlayerB
deriving (Eq, Show)
data BoardField = Coast | OpenSea | Ship Player
deriving (Eq, Show)
type Board = Int -> BoardField -- “array” of fields which may have ships in them, starting with index 0
amountOfShips :: Player -> Board -> Int
amountOfShips k board = go 0 0 -- the `board` is always the same, no need to pass
-- it explicitly to the worker-loop function `go`
where go x res = case board x of -- `case` is even better than guards, if all you're doing is equality comparison.
Coast -> res -- When we've reached the coast we're done, there can be no more ships.
Ship player
| player==k -> go (x+1) (res+1) -- Found ship of the requested player,
-- therefore continue recursion with incremented accumulator
_ -> go (x+1) res -- No ships here, so continue recusion with the same accumulator.
count_instances :: (Int)->([Int])->Int
count_instances x [] = 0
count_instances x (t:ts)
| x==t = 1+(count_instances x ts)
| otherwise = count_instances x ts
i just want to know whats so good about using guards in this Question ?
A guard can be a way to write only one half of an if-then-else expression; you can omit the else and have a partial function.
-- Leave the function undefined for x /= y
foo x y | x == y = ...
You can do the same with a case statement, but it's more verbose
foo x y = case x == y of
True -> ...
It's also easier to list several unrelated conditions as a set of alternatives than it is with a nested if-then-else or case expressions.
foo x y | p1 x y = ...
foo x y | p2 x y = ...
foo x y | p3 x y = ...
foo x y = ...
vs
foo x y = if p1 x y then ...
else (if p2 x y then ...
else (if p3 x y then ... else ...))
Patterns with guards are probably the most concise way to write code that otherwise would require nested case/if expressions.
Not the least advantage is that a where clause applies to all the guards right hand sides. This is why your example could be even more concise:
count_instances :: (Int)->([Int])->Int
count_instances x [] = 0
count_instances x (t:ts)
| x==t = 1+rest
| otherwise = rest
where rest = count_instances x ts
A guard is haskell's most general conditional statement, like if/then/else in other languages.
Your code shows a straight forward implementation of counting contents of a list equal to a given parameter. This is a good example to learn how haskell's recursion works.
An alternative implementation would be
count_instances :: Int -> [Int] -> Int
count_instances i = length . filter (==i)
that reuses already existing functions from the Prelude module. This is shorter and probably more readable.
this is an expansion to my last question here: basic haskell : Copying elements
however when an invalid input is added then I want it to print out an error message saying "negative value" or something similar. Is this possible in haskell?
working code:
copy :: Int->a->[a]
copy 0 _ = []
copy y a = [a]++(copy (y-1) a)
final line:
copy b c = error "negative value"
Because partial functions make me sad, I'd suggest doing something more along the lines of
copy :: Int -> a -> Maybe [a]
copy 0 _ = Just []
copy n a | n < 0 = Nothing
| otherwise = fmap (a:) (copy (n-1) a)
We've swapped out that if for a "guard"
foo bar | baz = quux
| ...
is just
foo bar = if baz then quux else ...
Note that I also changed your code a little,
[a] ++ copy (y-1) a ====> fmap (a:) (copy (y-1) a)
You can think of (:) as append.
1 : [2, 3] ==> [1, 2, 3]
It's the preferred alternative to [1] ++ [2, 3]. Say it out loud as "cons", like "construct". We can write this with an operator section
(a:) ==> \x -> a : x
Next we use this wonky fmap function. Think of fmap like this
fmap f Nothing = Nothing
fmap f (Just x) = Just (f x)
So it unwraps a Just and applies a function before rewrapping the result. So our final code returns Nothing if our number is negative, otherwise, just the list.
Why aren't I recommending error? Well because error will blow up your whole program with pretty minimal information and it's a bad idea to try to catch it. Haskell doesn't even mandate that it's possible to do so, GHC just implements error in such a way that it's possible. In other words, you have little chance to recover.
This isn't a big deal for 10 lines of code, but I've spent upwards of 6 hours searching for the offending call to a function using error. It's much faster to debug and more idiomatic haskell.
You can do this with guards
copy :: Int -> a -> [a]
copy n x
| n < 0 = error "negative value"
| n == 0 = []
| otherwise = x : copy (n - 1) x
However, if this fails then it will likely crash your program. A better way is to use the Maybe type:
copySafe :: Int -> a -> Maybe [a]
copySafe n x
| n < 0 = Nothing
| otherwise = Just (copy n x)
Then you can use it as
main = do
putStrLn "Enter a number:"
nStr <- getLine
let n = read nStr :: Int
maybeXs = copySafe n n
case maybeXs of
Nothing -> putStrLn "You entered a negative number!"
Just xs -> print xs
This style forces you to consider both cases of copySafe, either it can fail on a negative value or it can return a valid list. It doesn't crash your program and the error handling is enforced by the type system.
look at http://www.haskell.org/haskellwiki/Error_vs._Exception
for example
copy b c = if c > b then error "negativ value"