Georgi Angelov
Georgi Angelov

Reputation: 4388

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

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)

Upvotes: 5

Views: 4828

Answers (3)

kqr
kqr

Reputation: 15038

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."

Upvotes: 3

daniel gratzer
daniel gratzer

Reputation: 53901

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".

Upvotes: 10

Jeff Burka
Jeff Burka

Reputation: 2571

You could use the fromJust:: Maybe a -> a function. That will convert Just 4 into 4 for example. Be careful though, if you call fromJust Nothing it will throw an error.

To avoid the error, use fromMaybe, which takes a default value that will be returned if you pass a Nothing value to the function.

Upvotes: 2

Related Questions