Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell: use Maybe but print an actual number rather than "Just ... "

Tags:

haskell

max

So here is my program. I want to implement a maximum function on my own for an assignment. The problem is that to me it seems weird to print the number with the word "Just" in front of it... How would I fix this to print just a number?

mymax :: Ord a=>[a]->Maybe a
mymax [] = Nothing
mymax [x] = Just x
mymax (x:y:xs) = if x < y then mymax(y:xs) else mymax(x:xs)
like image 413
Georgi Angelov Avatar asked Sep 18 '13 04:09

Georgi Angelov


2 Answers

Well the Show instance for Maybe puts that Just there. If you don't want it the simple solution is to not use show

myPrint :: Show a => Maybe a -> IO ()
myPrint (Just x) = print x
myPrint n        = print n

Here we just unwrap Justs before tossing them to print.

The other option is to lose the Maybe. You can either do this with something like maybe

maybe (putStrLn "Nothing") print m

printMay = maybe (putStrLn "Nothing") print

This takes a value m :: Maybe a and if it's Just x tosses x to print. Otherwise it simply returns putStrLn "Nothing".

like image 141
Daniel Gratzer Avatar answered Sep 22 '22 15:09

Daniel Gratzer


You have a ton of alternatives here! This following solution is exactly what you asked for, no more, no less: *

printMaybe :: Show a => Maybe a -> IO ()
printMaybe m = when (isJust m) $
                 print (fromJust m)

This will print the argument maybe value if it is a Just value, and otherwise do nothing at all. However, it's not the greatest of solutions in most cases. Any time you see fromJust you should regard it as a red flag. In this case, the problem is that the Nothing case is not handled at all. We would probably want to inform the user or at least do something when the list was empty. Then again, maybe we don't, and then this solution is fine.

Another case is if you would want to print something when the value is Nothing, in which case you can use the maybe function.

printMaybe m = maybe (putStrLn "List was empty!") print m

This will print "List was empty!" if m contains Nothing, otherwise it will print m. This is of course equivalent to

printMaybe = maybe (putStrLn "List was empty!") print

You could also implement this with pattern matching manually, like so:

printMaybe m = case m of
  Nothing -> putStrLn "List was empty!"
  Just x -> print x

which is equivalent, but slightly more code. In the same vein, you could explicitly do

printMaybe m = case m of
  Nothing -> return ()
  Just x -> print x

if you want the function to not do anything at all when it gets a Nothing value, like the first function in my answer.


* This could be written more neatly by using the applicative instance of functions, like this:

printMaybe = liftA2
  when isJust $ print . fromJust

This does quite literally what it reads as. "When the argument is a Just, print what you get from the Just."

like image 21
kqr Avatar answered Sep 25 '22 15:09

kqr