How do I print variables from inside a function? - haskell

So I have a main function (foo) that recursively calls two other functions (step1 & step2). foo will add a1 to a2 a count amount of times and then return (a1, a2). How can I print the variables count, a1, and a2 at each step?
-- adds a1 to a2 a `count` number of times
-- returns (a1, a2) once count reaches 0
foo :: Integer -> Integer -> Integer -> (Integer, Integer)
foo count a1 a2 | count == 0 = (a1,a2)
| otherwise = foo count' a1' a2'
where (count', a1', a2') = let (count'', a1'', a2'') = step1 count a1 a2
in step2 count'' a1'' a2''
-- adds a2 to a1. How to print out count, a1 and a2' here?
step1 :: Integer -> Integer -> Integer -> (Integer, Integer, Integer)
step1 count a1 a2 = (count, a1, a2')
where
a2' = a1 + a2
-- decrements count by 1. How to print out count', a1 and a2 here? Or can I do these prints somewhere in the `foo` function?
step2 :: Integer -> Integer -> Integer -> (Integer, Integer, Integer)
step2 count a1 a2 = (count', a1, a2)
where
count' = count - 1
This is a simplified version of code from a larger code base. I am open to using a different approach. The example output that I am looking for is:
$> foo 3 4 5
3 4 5
3 4 9
2 4 9
2 4 13
1 4 13
1 4 17
0 4 17
(4, 17)
EDIT: I just realized I could probably store intermediary results in a list and then print from that list. But am I correct to think that I would have to pass the list as an argument to the functions?

You have to change foo and make it operate in the IO monad. Effectively this "tags" the function as being impure (i.e. it has side effect, such as printing on stdout) which allows it to call functions such as print. Here's an example:
foo :: Integer -> Integer -> Integer -> IO (Integer, Integer)
foo count a1 a2 = do
print (count, a1, a2)
case count of
0 -> do
print (a1,a2)
return (a1,a2)
_ -> do
let (count'', a1'', a2'') = step1 count a1 a2
(count', a1', a2') = step2 count'' a1'' a2''
foo count' a1' a2'
Note: If you want to print these values for debugging purposes, then you can use Debug.Trace as shown in chepner's answer. You should do that for debugging purposes only and for no other reason.

For debugging purposes only, you can use Debug.Trace. For example:
import Debug.Trace
-- adds a2 to a1. How to print out count, a1 and a2' here?
step1 :: Integer -> Integer -> Integer -> (Integer, Integer, Integer)
step1 count a1 a2 = traceShowID (count, a1, a2')
where
a2' = a1 + a2
-- decrements count by 1. How to print out count', a1 and a2 here? Or can I do these prints somewhere in the `foo` function?
step2 :: Integer -> Integer -> Integer -> (Integer, Integer, Integer)
step2 count a1 a2 = traceShowID (count', a1, a2)
where
count' = count - 1
traceShowID :: Show a => a -> a is basically id with the (unannounced) side effect of also printing the argument's string representation according to show.

Related

How to count number of times guard statement happens in recursion?

I'm new to haskell and I got stuck in a little program I tried to make. I want to count number of times my guard statement goes through in all recursion rounds and then return that as Int. For example if c1 is 'a', c2 is 'b', g is 2 and s is "aaabbb" then returned int would be 2, because my guard statement is true in 2 cases.
I tried to make variable x and then add x + 1 to it every time guard statement happens. That didn't work because I learnt that in Haskell variable you set is always static so for example setting x = 0 at start would set that x to 0 every recursion round.
Here's my code:
gaps :: (Char, Char) -> Int -> String -> Int
gaps (c1,c2) g (s:xs)
| c1 == s && c2 == (s:xs) !! g = --Count how many times this statement happens --
| otherwise = gaps (c1,c2) g xs
Just add 1 and call the function recursively
gaps :: (Char, Char) -> Int -> String -> Int
gaps _ _ [] = 0 -- base case
gaps (c1,c2) g (s:xs)
| c1 == s && c2 == (s:xs) !! g = 1 + gaps (c1,c2) g xs -- add one to final result
| otherwise = gaps (c1,c2) g xs
> gaps ('a','b') 2 "aaabbb"
2
> gaps ('a','b') 3 "aaaabbbb"
3
Be carefull when using !!. It isn't total and might fail if your input string has c1's values less than g positions before the end of the string
> gaps ('a','b') 3 "aaaababbb" -- doesn't fail
3
> gaps ('a','b') 3 "aaaabbabb" -- does fail!!!!
Off the back of questions on how to make this thing safer, I have made the following code snippet, borrowing from Ismor's answer.
-- a way to safely get the nth item from a list
get' :: [a] -> Int -> Maybe a
get' [] _ = Nothing
get' (x:xs) 0 = Just x
get' (x:xs) n
| n > 0 = get' xs (n-1)
| otherwise = Nothing
-- takes a Maybe value. if it's Nothing, return 0. if it's Just a value, compare
-- the value and a given param, if equal return 1, else 0
seeEqual:: (Num b, Eq a) => Maybe a -> a -> b
seeEqual Nothing _ = 0
seeEqual (Just a) b
| a==b = 1
| otherwise = 0
-- I have edited the first guard so that it checks c1 and s, then tries to calculate
-- whether c2 and the specific list item are equal, and then recurses as before
gaps :: (Char, Char) -> Int -> String -> Int
gaps _ _ [] = 0 -- base case
gaps (c1,c2) g (s:xs)
| c1 == s = (seeEqual (get' (s:xs) g) c2) + gaps (c1,c2) g xs -- add one to final result
| otherwise = gaps (c1,c2) g xs
I do not claim that this is perfect, but I do think this is safe and shouldn't throw any exceptions or raise any errors.
Prelude> gaps ('a','b') 3 "aaaababbb"
3
Prelude> gaps ('a','b') 3 "aaaabbabb"
2

Haskell code using a pre definite variable

Could anybody tell me why the following code in Haskell is not working?
a = 5
foo :: Int -> Int -> Int
foo a 0 = 0
foo a b = a + foo a (b - 1)
where
a = a + 1
In Haskell a variable is in scope during its definition, so in a = a + 1, the a is referring to itself. If we rename the variables in your code, so that all variables have unique names, it will look like this:
a1 = 5
foo :: Int -> Int -> Int
foo _ 0 = 0
foo a2 b = a3 + foo a3 (b - 1)
where
a3 = a3 + 1
So the problem here is that a3 = a3 + 1 is infinitely recursive - a3 can't be equal to its own value plus one. Also a2 is never used.
You said that you wanted it to refer to the value of the parameter, so now that the variables have different names we can fix this easily enough:
foo :: Int -> Int -> Int
foo _ 0 = 0
foo a2 b = a3 + foo a3 (b - 1)
where
a3 = a2 + 1
Note that I've left out a1 this time since it's irrelevant to the foo function. We can also get rid of the where and just inline the a2 + 1 part (and rename a2 back to a since there will no longer be multiple ones):
foo :: Int -> Int -> Int
foo _ 0 = 0
foo a b = (a + 1) + foo (a + 1) (b - 1)

How to convert the column name to its column index in Haskell

Excel column names are like A, B, C ... AA, AB, AC up to infinite. How can i convert the column name to its column index in Haskell. I can convert index to column but couldnt make the reverse function. Can someone explain me how to write the reverse function of it ? Index to column:
f n = (concatMap sequence $ tail $ iterate (['A'..'Z'] :) []) !! n
Excel columns are simply numbers in Base26, with digits A-Z.
Use readInt from Numeric.
xlColumnToNumberR :: ReadS Int
xlColumnToNumberR = readInt 26 -- There are 26 letters
isAlpha -- From 'Data.Char'
xlValue
where xlValue c = ord (toUpper c) - ord 'A' + 1
xlColumnToNumber :: String -> Maybe Int
xlColumnToNumber n = case xlColumnToNumberR n of
[(x, "")] -> Just x
_ -> Nothing

SmallCheck series generation and duplicates (the parameters have relations)

The following data structure can be tested with the Tasty-SmallCheck related code that follows. There is a relation that has to hold with the constructor ShB: the second and the third positive integers should be at most as large as the first one.
data Shape = ShA Int Int Bool
| ShB Int Int Int Bool Bool
deriving (Show,Read,Eq)
The constructor ShA should have positive Int's but otherwise there is no relation between the parameters.
auxShA :: (Positive Int, Positive Int, Bool) -> Shape
auxShA (i,j,b) = ShA (fromIntegral i) (fromIntegral j) b
auxShB :: (Positive Int, Positive Int, Positive Int) -> Bool -> Bool -> Shape
auxShB (a1,a2,a3) = ShB i u d
where
(i,u,d) = auxTriplet (a1,a2,a3)
auxTriplet :: (Positive Int, Positive Int, Positive Int) -> (Int,Int,Int)
auxTriplet (a,b,c)
| a >= b && a >= c = (fromIntegral a, fromIntegral b, fromIntegral c)
| b >= a && b >= c = (fromIntegral b, fromIntegral a, fromIntegral c)
| otherwise = (fromIntegral c, fromIntegral a, fromIntegral b)
consB :: (Serial m a1, Serial m a2, Serial m a3, Serial m b, Serial m c) =>
((a1,a2,a3) -> b -> c -> e) -> Series m e
consB f = decDepth $
f <$> series
<~> series
<~> series
instance Monad m => Serial m Shape where
series = cons1 auxShA \/ consB auxShB
The generated cases are otherwise ok but there are duplicates that can be seen e.g. with
list 4 series :: [Shape]
The question is, how to generate the test cases with SmallCheck (tasty) when the following holds?
there are properties that has to hold, e.g. the first parameter has to Positive
what if the first parameter should be larger than 10::Int?
And continuing, what if the second parameter should between the first - 5 and the first, and the third should be between the second - 5 and the second?
Or, how to generate test cases that dynamically can depend on the previous generated values?
First thought was to write constructors to Shape that check that inputs are valid (e.g. the bullet points above), but the problem of duplicate test case generation would remain with that approach.
The above code uses similar solution as in
SmallCheck invariant -answer.

Pattern-matching in case, Haskell

I'm fairly new to Haskell and have a question about pattern-matching.
Here is a heavily simplified version of the code:
data Value = MyBool Bool | MyInt Integer
codeDuplicate1 :: Value -> Value -> IO Value
codeDuplicate1 = generalFunction True
codeDuplicate2 :: Value -> Value -> IO Value
codeDuplicate2 = generalFunction False
generalFunction :: Bool -> Value -> Value -> IO Value
generalFunction b x1 x2 = do result <- eval x1
case result of
MyBool b -> do putStrLn $ show b
return (MyBool b)
_ -> eval x2
eval :: Value -> IO Value
eval (MyInt x) | x > 10 = return (MyInt 10)
| x > 5 = return (MyBool True)
| otherwise = return (MyBool False)
Now, I realize that the argument b in generalFunction is not the same as the b in the case part, and therefore, this code will print b regardless of the input. I used the same name just to show my intentions. So my question is:
Is there a way to match the first b with the second, so that if the bs are the same it will print, otherwise it will evaluate x2? And, if there isn't, is there another good way to get the intended result?
I almost found the answer in this question, but I think this situation is slightly different.
You can use a guarded pattern. The first alternative will be executed if MyBool is matched and b == b2; otherwise the second alternative will be executed.
case result of
MyBool b2 | b == b2 -> do {print b; return $ MyBool b}
_ -> eval x2

Resources