user1008893
user1008893

Reputation:

Printing in Haskell

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?

Upvotes: 1

Views: 1579

Answers (2)

Antti
Antti

Reputation: 12479

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.

Upvotes: 3

Theo Belaire
Theo Belaire

Reputation: 3020

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.

Upvotes: 5

Related Questions