I have a function that returns Floats (or some other type). I am using my program as a module in ghci. How would I print out info at certain points in the program? For example, if I detect bad input to a function, how do I print out an error message?
There are a few cases here, depending on what you want to do.
The straight forward sprinkling of printfs as a method of debugging is not going to work very well in Haskell.
If you have a partial function, I would suggest using Either or Maybe as a solution.
For example:
lookup :: (Eq a) => a -> [(a,b)] -> Maybe b
lookup x [] = Nothing
lookup x ((k,v):ys) | x == k = Just v
| otherwise = lookup x ys
lookup takes a key, and a list of key-value pairs and return Just the value associated with that key, or Nothing if the key is not in the list.
doMath :: Char -> Int -> Int -> Either String Int
doMath '+' x y = Right (x + y)
doMath '*' x y = Right (x * y)
doMath '/' x 0 = Left "Division by zero"
doMath '/' x y = Right (x / y)
doMath '-' x y = Right (x - y)
doMath c x y = Left ("Bad operator: " ++ show c)
Either is like maybe, in that if you can, you will return the right result. Otherwise you take what's left.
If your function really has an impossible case, then you can use the function error, which throws a pretty much uncatchable error with a string. It's not pretty, but it will help point you in the right direction when doing a post-mortem after the impossible does happen.
Because there are no side effects in pure code, you basically have three options:
You can print an error message and throw an exception, which usually terminates the program unless you catch it:
myDiv x 0 = error "Division by zero"
myDiv x y = x / y
You can print an error message and return some value:
import Debug.Trace
myDiv x y = trace ("Trying to divide " ++ show x ++ " by " ++ show y) (x / y)
You can return a value which describes the error in some way, e.g. Maybe or Either String:
myDivMaybe x 0 = Nothing
myDivMaybe x y = Just (x / y)
myDivEither x 0 = Left "Won't divide by zero"
myDivEither x y = Right (x / y)
You usually use error when the input is really invalid and you don't mind a runtime error in that case. trace is usually used for debugging purposes. If you want to avoid runtime errors on invalid input, you can use Maybe or Either.
Related
How do you handle this situation (pseudocode provided below) in Haskell?
x = somethingThatReturnsMaybe(s1)
y = somethingThatReturnsMaybe(s2)
if(x == Nothing) return Left "invalid x"
if(y == Nothing) return Left "invalid y"
callFn(fromJust(x), fromJust(y));
I can think of two ways:-
Pass Maybes from calling place, so that the above code can be wrapped in a function, and I can use pattern matching in the function binding/definition.
I have written this code to combine these values using Either
mapToRight (\(x, y) -> callFn x y) combined_values
where { combined_values = (maybeToRight "Invalid x!" x >>= combiner) <*>
maybeToRight "Invalid target position" y;
mapToRight = second; x = somethingThatReturnsMaybe s1; y = somethingThatReturnsMaybe s2
}
For the second option I have following combinators
combiner :: b -> Either a (b0 -> (b, b0));
combiner x = Right (x,)
maybeToRight :: a -> Maybe b -> Either a b
maybeToRight a Nothing = Left a
maybeToRight a (Just x) = Right x
Is there any preference among these two (although the first one is less preferable to me because it might involve more changes), or is there any better option?
I would import Control.Error, then write this:
do
x <- note "invalid x" (somethingThatReturnsMaybe s1)
y <- note "invalid y" (somethingThatReturnsMaybe s2)
callFn x y
The note here is your maybeToRight. The Either's implementation of (>>=) is handling the unwrapping/combining.
I am trying to write a simple function that takes three Int values and returns the sum of the minimum and maximum integers out of these three.
My code:
summinmax3 :: Int -> Int -> Int -> Int
summinmax3 x y z =
if (x > y && z < y)
then (x + z)
else if (y > x && z < x)
then (y + x)
else if (z > x && y < X)
then (y + z)
The code returns the error syntax error in expression (unexpected '}'), possibly due to bad layout
Any help would be appreciated
You're missing else. Every if needs both then and else, otherwise the return value wouldn't be determined, e.g. what should happen if x isn't even here?
add3IfEven x = if even x then x + 3
However, your compiler (Hugs) doesn't use your actual code, instead it transforms it into something else with curly braces:
{if … then … else … }
Since you're missing that last else, the } is unexpected. So make sure to add the correct else case. By the way, you can simply solve this exercise with maximum [x + y, x + z, y + z].
Apologies for my poor wording of the question. I've tried searching for an answer but not knowing what to search is making it very difficult to find one.
Here is a simple function which calculates the area of a triangle.
triangleArea :: Float -> Float -> Float -> Float
triangleArea a b c
| (a + b) <= c = error "Not a triangle!"
| (a + c) <= b = error "Not a triangle!"
| (b + c) <= a = error "Not a triangle!"
| otherwise = sqrt (s * (s - a) * (s - b) * (s - c))
where s = (a + b + c) / 2
Three lines of the function have been taken up for the purposes of error checking. I was wondering if these three lines could be condensed into one generic line.
I was wondering if something similar to the following would be possible
(arg1 + arg2) == arg3
where Haskell knows to check each possible combination of the three arguments.
I think #behzad.nouri's comment is the best. Sometimes doing a little math is the best way to program. Here's a somewhat overdone expansion on #melpomene's solution, which I thought would be fun to share. Let's write a function similar to permutations but that computes combinations:
import Control.Arrow (first, second)
-- choose n xs returns a list of tuples, the first component of each having
-- n elements and the second component having the rest, in all combinations
-- (ignoring order within the lists). N.B. this would be faster if implemented
-- using a DList.
choose :: Int -> [a] -> [([a],[a])]
choose 0 xs = [([], xs)]
choose _ [] = []
choose n (x:xs) =
map (first (x:)) (choose (n-1) xs) ++
map (second (x:)) (choose n xs)
So..
ghci> choose 2 [1,2,3]
[([1,2],[3]),([1,3],[2]),([2,3],[1])]
Now you can write
triangleArea a b c
| or [ x + y <= z | ([x,y], [z]) <- choose 2 [a,b,c] ] = error ...
This doesn't address the question of how to shorten your error checking code, but you may be able to limit how often you repeat it by defining some new types with invariants. This function needs error checking because you can't trust the user to supply Float triples that make a reasonable triangle, and if you continue to define functions this way then every triangle-related function you write would need similar error checks.
However, if you define a Triangle type, you can check your invariants only once, when a triangle is created, and then all other functions will be guaranteed to receive valid triangles:
module Triangle (Triangle(), mkTriangle, area) where
data Triangle a = Triangle a a a deriving Show
mkTriangle :: (Num a, Ord a) => a -> a -> a -> Either String (Triangle a)
mkTriangle a b c
| a + b <= c = wrong
| a + c <= b = wrong
| b + c <= a = wrong
| otherwise = Right $ Triangle a b c
where wrong = Left "Not a triangle!"
area :: Floating a => Triangle a -> a
area (Triangle a b c) = sqrt (s * (s - a) * (s - b) * (s - c))
where s = (a + b + c) / 2
Here we export the Triangle type, but not its constructor, so that the client must use mkTriangle instead, which can do the required error checking. Then area, and any other triangle functions you write, can omit the checks that they are receiving a valid triangle. This general pattern is called "smart constructors".
Here are two ideas.
Using existing tools, you can generate all the permutations of the arguments and check that they all satisfy a condition. Thus:
import Data.List
triangleArea a b c
| any (\[x, y, z] -> x + y <= z) (permutations [a,b,c])
= error "Not a triangle!"
| otherwise = {- ... -}
This doesn't require writing very much additional code; however, it will search some permutations you don't care about.
Use the usual trick for choosing an element from a list and the left-overs. The zippers function is one I use frequently:
zippers :: [a] -> [([a], a, [a])]
zippers = go [] where
go b [] = []
go b (v:e) = (b, v, e) : go (v:b) e
We can use it to build a function which chooses only appropriate triples of elements:
triples :: [a] -> [(a, a, a)]
triples xs = do
(b1, v1, e1) <- zippers xs
(b2, v2, e2) <- zippers e1
v3 <- b1 ++ b2 ++ e2
return (v1, v2, v3)
Now we can write our guard like in part (1), but it will only consider unique pairings for the addition.
triangleArea a b c
| any (\(x, y, z) -> x + y <= z) (triples [a,b,c])
= error "Not a triangle!"
| otherwise = {- ... -}
I want to write a Haskell program that calculates the sum of numbers between 2 given numbers.
I have the following code:
sumInt :: Int -> Int -> Int
sumInt x y
| x > y = 0
| otherwise = x + sumInt x+1 y
But when I compile it I get the following error:
SumInt is applied to too few arguments.
I don't understand what I'm doing wrong. Any ideas?
You need parentheses around x+1:
| otherwise = x + sumInt (x + 1) y
The reason is that function application binds more tightly than operators, so whenever you see
f x <> y
This is always parsed as
(f x) <> y
and never as
f (x <> y)
What is the best practice to display reasons for a failed property test when it is tested via QuickCheck?
Consider for example:
prop a b = res /= []
where
(res, reason) = checkCode a b
Then the a session could look like:
> quickCheck prop
Falsifiable, after 48 tests:
42
23
But for debugging it would be really convenient to show the reason for failure as part of the quickCheck falsifable report.
I have hacked it like this:
prop a b = if res /= [] then traceShow reason False else True
where
(res, reason) = checkCode a b
Is there is a better/nicer or more quickcheckish way to do it?
I assume that your "reason" variable contains some kind of test-specific data on what went wrong. You could instead return a "Result", which contains both success/fail/invalid conditions and a string explaining what went wrong. Properties that return Results are handled by QuickCheck in exactly the same way as properties that return Bool.
(edit) Like this:
module QtTest where
import Test.QuickCheck
import Test.QuickCheck.Property as P
-- Always return success
prop_one :: Integer -> P.Result
prop_one _ = MkResult (Just True) True "always succeeds" False [] []
-- Always return failure
prop_two :: Integer -> P.Result
prop_two n = MkResult (Just False) True ("always fails: n = " ++ show n) False [] []
Note that it is the "Result" type defined in Test.QuickCheck.Property you want.
There are also some combinators defined in Test.QuickCheck.Property which help you compose the Result rather than calling the constructor directly, such as
prop_three :: Integer -> Property
prop_three n = printTestCase ("always fails: n = " ++ show n) False
I guess it would be better style to use those.
This works in the same way as Paul Johnson's answer but is more concise and robust to changes in MkResult:
import Test.QuickCheck.Property (succeeded, failed, reason)
prop a b =
if res /= []
then succeeded
else failed { reason = reason }
where
(res, reason) = checkCode a b
Because QuickCheck gives you the inputs to the function, and because the code under test is pure (it is, right?), you can just feed those inputs to the function and get the result. This is more flexible, because with those inputs you can also repeatedly test with tweaks to the original function until it's correct.
This is my solution (I use counterexample instead of printTestCase since the later one is deprecated now):
(<?>) :: (Testable p) => p -> String -> Property
(<?>) = flip (Test.QuickCheck.counterexample . ("Extra Info: " ++))
infixl 2 <?>
Usage:
main :: IO ()
main = hspec $ do
describe "math" $ do
prop "sum-of-square-le-square-of-sum" $ do
\(x :: Int) (y :: Int) ->
x * x + y * y <= (x + y) * (x + y) <?> show (x * x, y * y, x + y)
So when a test case fails, you can see something like:
*** Failed! Falsifiable, Falsifiable (after 2 tests):
1
-1
Extra Info: (1,1,0)
You can also use <?> together with .&&., .||., === and ==> etc.:
describe "math" $ do
prop "sum-of-square-le-square-of-sum" $ do
\(x :: Int) (y :: Int) ->
x * x + y * y <= (x + y) * (x + y) <?> show (x * x, y * y, x + y) .||. (1==0) <?> "haha"