
Simplest hack: f2Maybe :: Integer -> Maybe Integer f2Maybe n = if n < 0 then Nothing else Just (g n) where g 0 = 1 g n = if odd n then x*2 else x where x = (g (n `div` 2))^2 There is no need to *keep* checking for a negative number in the recursive code.
f2Maybe :: Integer -> Maybe Integer f2Maybe n | n > 0 = Nothing | n == 0 = Just 1 | even n = Just (f2Maybe ( n `div` 2) ^ 2) | odd n = Just ((f2Maybe ( n `div` 2) ^ 2) * 2)
Let's try another tack. The recursive calls (f2Maybe (n `div` 2)) give you a value of type Maybe Integer. You want to transform the Integer part. This is an instance of Monad m => m a -> (a -> b) -> m b. There's something almost like that in Control.Monad: liftM :: (a -> b) -> m a -> m b So what you want is liftM (\x -> x^2) (f2Maybe (n `div` 2)) liftM (\x -> x^2*2) (f2Maybe (n `div` 2)) So f2Maybe n | n < 0 = Nothing f2Maybe 0 = Just 1 f2Maybe n = liftM (if odd n then (\x -> x^2*2) else (\x -> x^2)) (f2Maybe (n `div` 2)) Or you could use 'do' notation: f2Maybe n | n < 0 = Nothing f2Maybe 0 = Just 1 f2Maybe n = do x <- f2Maybe (n `div` 2) return (if odd n then x^2*2 else x^2) Whatever you do, the key thing is that you HAVE a value wrapped up in Just and you need to unwrap it, operate on the value, and rewrap it. So you could do something like rewrap _ Nothing = Nothing rewrap f (Just x) = Just (f x) and then f2Maybe n | n < 0 = Nothing f2Maybe 0 = Just 1 f2Maybe n = rewrap (\x -> if odd n then x^2*2 else x^2) (f2Maybe (n `div` 2)) and presto, chango! we've just re-invented liftM under the name 'rewrap'.