3

I'm newbie of Haskell. And I'm learning about monads.

data Container a = Container a deriving Show

x = Container 1 :: Container Int

plusOne :: Container Int -> Container Int
plusOne (Container x) = Container (x+1)

Is there any way to lift plusOne to apply to Container (IO Int)?

Or should I define a new function, such as:

plusOne' :: Container (IO Int) -> Container (IO Int)  
plusOne' (Container x) = Container (liftM (+1) x)

Thanks all :-) And then Is there any way to avoid redefine plusOne ?

Because whan I build program, first I build program with non-monadic-type container(normal value such as: Container Int ..etc), And I test function with specified value (Container 10..).

And after that I try to apply these program to random or generated value. This is my basic approach for programming in other language (such as Lisp, Python..)

So I don't want to redefine function when I want to try to apply these function to monadic-value container.

this approach doesn't work on Haskell programming? Should I change my mind-model? Or I misunderstanding about Haskell?

Pocket7878
  • 91
  • 6

2 Answers2

8

Looks like Container should be an instance of Functor:

instance Functor Container where
    fmap f (Container a) = Container (f a)

Then

plusOne = fmap (+1)

and

plusOne' = fmap $ liftM (+1)

However, now it occurs to me that I might have misunderstood the question...

Koterpillar
  • 7,883
  • 2
  • 25
  • 41
7

First things first, it looks like you've actually redefined the Identity monad.

When you have functors containing other functors as you do here, you don't want to have to do all the bookkeeping yourself to make sure you've got the right number of fmaps and so on. That's where monad transformers come in.

The MTL library (which should come with the Haskell Platform) has done all the hard work for you, you just need to do a bit (OK, quite a lot) of plumbing to make your own type work with all the existing monad transformers. Once you've done that, your Container should be a good citizen as a member of any monad stack.

Of course, the usual caveats apply: monad transformers are powerful and hard to understand. Half the times you think you need them, you don't really - so make sure you're using the right approach to solve your problem first.

Benjamin Hodgson
  • 42,952
  • 15
  • 108
  • 157
  • Simon Marlow (one of the core authors of GHC) [says](http://stackoverflow.com/questions/3247280/whats-the-next-step-to-learning-haskell-after-monads#comment3359385_3247280) that in GHC "we never even use monad transformers". So, as I said above, most of the times you think you need them, you actually don't. – Benjamin Hodgson Apr 21 '13 at 20:44