3

When I use fmap over a value, it essentially "unboxes" that value, applies the function to it, and boxes it back up.

For example:

-- returns Just 8
fmap (+3) (Just 5)

Is there any function that gives me the value without boxing it back up?

-- returns 8
fmap_2 (+3) (Just 5)

Granted, I don't know how this would work for arrays, but it would be useful for Eithers and Maybes, for starters. I could also use it to mix Monads easily:

-- myfunc :: Maybe Int

-- if myfunc returned a Just, show it and then print it. Otherwise, print 'Nothing'.
putStrLn . fmap show $ myfunc

Or is there another standard way of mixing Monads?

Vlad the Impala
  • 15,572
  • 16
  • 81
  • 124
  • 5
    No, there's no standard way of mixing monads. There cannot be. Monads do not commute. However, *some* monads can be mixed in their own special ways. An established method of packaging such a special way of monad mixing is called a monad transformer. There are several libraries of monad transformers out there, and extensive literature. Just google "monad transformers". – n. m. could be an AI Feb 27 '12 at 07:24
  • Take a look: [How to extract value from monadic action?](http://stackoverflow.com/questions/8567743/how-to-extract-value-from-monadic-action) – ДМИТРИЙ МАЛИКОВ Feb 27 '12 at 07:24

3 Answers3

11

For extracting Maybe use maybe:

maybe 0 (+3) $ Just 5
>>> 8
maybe 0 (+3) Nothing
>>> 0

You should use fromJust only when getting a Nothing must be considered as an abnormal situation. Don't evolve a habit of crashing your program without a really good reason to. The Maybe and Either are there exactly to help you avoid that.

For Either there is a function either:

either (*2) (+2) $ Left 3
>>> 6
either (*2) (+2) $ Right 3
>>> 5

Please note that in correct code you won't need to extract monads often. That's kinda whole point about them and Haskell has to offer all the tools you may need to work with monadic values as if they were extracted.

Nikita Volkov
  • 42,792
  • 11
  • 94
  • 169
5

This function cannot exist for all functors. Even for simple ones like Maybe, it would not work if you had a Nothing. For IO, this would let you do arbitrary IO in your program and be decidedly unsafe. Finally, for some slightly weirder functors (like (->) e which is just a function taking an argument of type e), this would not even make any sense.

However, for some types that are functors, this function exists. For example, there is a function called fromJust that has a type Maybe a -> a. However, if you pass this function a Nothing, you will get a runtime error.

So, a function like this could exist for some types that are also instances of Functor, but it does not make sense for the Functor class itself.

Tikhon Jelvis
  • 67,485
  • 18
  • 177
  • 214
2

import Control.Comonad (extract)

Vagif Verdi
  • 4,816
  • 1
  • 26
  • 31