I think that these are therefore the responses to the original questions: > I am of the understanding that once you into a monad, you cant get out of it?
You can run monadic functions and get pure results. So it looks like in that sense you can "get out of it". > Is this breaking the "monad" scheme? Apparently not. Although functions that do this for monads that have side effects are unsafe, so use them carefully. Cheers, Kevin On Jul 30, 11:17 am, Anton van Straaten <an...@appsolutions.com> wrote: > >> On Jul 30, 9:59 am, Kevin Jardine <kevinjard...@gmail.com> wrote: > >> > >>> The original poster states that the type of modifiedImage is "simply > >>> ByteString" but given that it calls execState, is that possible? > >>> Would it not be State ByteString? > > >> Oops, I should have written > >> > >> IO ByteString > >> > >> as the State stuff is only *inside* execState. > >> > >> But a monad none the less? > > State is a pure monad that doesn't involve IO. It works by threading a > state value through the monadic computation, so old states are discarded > and new states are passed on, and no actual mutation is involved. This > means there's no need to bring IO into it. > > If you look at the type signature of execState, you'll see that unless > the state type 's' involves IO, the return type can't involve IO. > > It can help to run little examples of this. Here's a GHCi transcript: > > Prelude> :m Control.Monad.State > Prelude Control.Monad.State> let addToState :: Int -> State Int (); > addToState x = do s <- get; put (s+x) > Prelude Control.Monad.State> let mAdd4 = addToState 4 > Prelude Control.Monad.State> :t mAdd4 > m :: State Int () > Prelude Control.Monad.State> let s = execState mAdd4 2 > Prelude Control.Monad.State> :t s > s :: Int > Prelude Control.Monad.State> s > 6 > > In the above, addToState is a monadic function that adds its argument x > to the current state. mAdd4 is a monadic value that adds 4 to whatever > state it's eventually provided with. When execState provides it with an > initial state of 2, the monadic computation is run, and the returned > result is 6, which is an Int, not a monadic type. > > > Or is it possible to call a function in a monad and return a pure > > result? I think that is what the original poster was asking? > > If you use a function like execState (depending on the monad), you can > typically run a monadic computation and get a non-monadic result. > However, if you're doing that inside a monadic function, you still have > to return a value of monadic type - so typically, you use 'return', > which lifts a value into the monad. > > > I know that unsafePerformIO can do this, but I thought that was a bit > > of a hack. > > IO is a special monad which has side effects. unsafePerformIO is "just" > one of the functions that can run IO actions, but because the monad has > side effects, this is unsafe in general. With a pure monad like State, > there's no such issue. > > Anton > > _______________________________________________ > Haskell-Cafe mailing list > haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe