Movatterモバイル変換


[0]ホーム

URL:


Jump to content
HaskellWiki
Search

What a Monad is not

From HaskellWiki

Warning

Don't be surprised if you leave this page more confused than before. That justmeans that it has successfully destroyed your false assumptions, or that you'vefallen for some horrible inside joke. Beware ofzygohistomorphic prepromorphisms. Go forwarm and fuzzy,instead. Orthis one.

Could the monadic interface be a good topic for the first entry of a new Haskell blog?

If and only if you're a categorist(no,not just a mathematician, but a fully-certifiable categorist). Otherwise, justaccept that they'reburritos,and wait until later...much later.

Is the monadic interface a language feature?

No - really, no. In Haskell, the monadic interface is defined as just anothertype class: likeEq a,Ord a, and so forth. Conversely:

Does that mean Haskell really needs the monad interface?

No - absolutely not.It could be done differently and still work.The monadic interface was first introduced to Haskell as areplacement for its originaldialogue-based I/O; these daysthere's alsoarrow-based I/O.

So If you are willing to put in the work, you could systematically expunge themonadic interface from your preferred Haskell implementation! Just remember toprovidesome backwards-compatibility for all that old monadic Haskellcode out there, for I/O...and everything else.(Or you could juststart an all-new language withnon-strict semantics.;-)

Are monads pure?

No! You don't even need flexible morals to claim it. But admit it: this isspecifically about just one monadic type -IO a. So here it is:

  • IfIO a is pure:
foreign import ccall "stdlib.h" rand :: IO Int
thenthe C language is purely functional.

However:

  • If Haskell is impure, then effects (like those of I/O) could be used conveniently:
trace :: [Char] -> b -> b
trace msg x = let !_ = putStrLn msg in x
as they can in most other impure languages, like Standard ML.

But both of those statementsare false.

For monadic I/O in Haskell, "pure" or "impure" are meaningless labels. Moregenerally, "purity" or "impurity" isn't a property of the monadic interface -if a monadic type is impure, it's because of the type, not the interface.

Is the monadic interface just about state?

No:

unitMaybe :: a -> Maybe aunitMaybe x = Just xbindMaybe :: Maybe a -> (a -> Maybe b) -> Maybe bbindMaybe (Just x) k = k xbindMaybe Nothing  _ = Nothing

While it is certainly possible to abstract away explicit state passing by usingthe monadic interface, that isn't what it is. Other examples of monadictypes that are not about state include

Does the monadic interface have something to do with strictness?

No. By themselves, the two basic monadic operations (return and(>>=) in Haskell) are neither strict or non-strict. It's the typewhich implements those operations that determines their strictness:IO a is strict, but[a] isn't. Then there are some that canbe both, likeState s a.

Try the following:

runState (sequence . repeat $ state (\x -> (x,x+1))) 0

Having a look at theimplementation offixIOmight be helpful, too.

Does the monadic interface somehow "represent" values?

No. This point might be made best by noting thatinstance Monad Foo where ... is not a data type, but an instancedeclaration for the type classMonad a. However, to elaborate:

Just as numeric operations like addition and multiplication don't representnumbers, monadic operations of the monadic interface don't represent values.The monadic interface expresss a -- very specific -- relationship betweenvalues of a specific domain into a common abstraction. We're going to callthe values of that abstractionmobits, somewhat like this:

type Mobit m a = Monad m => m a

  • IO a manages mobits representing side-effects ("I/O actions").
  • [a] manages mobits representing multiple values ("lists").
  • Reader a manages mobits that are pure computations that ask to propagate information instead of using explicit arguments.

...and while addition and multiplication are both monoids over the positivenatural numbers, a monad object is a monoid object in a category ofendofunctors:return is the unit, and(>>=) is the binarycomposition operation. It couldn't be more simple. If that confuses you, itmight be helpful to seeMonad a as a lax functor from a terminalbicategory.

Can the applicative-functor interface replace the monadic interface?

No. Instead, every monadic typeis an applicative functor (as well as afunctor). It is considered good practice not to use(>>=) if all youneed is(<*>), or evenfmap.

Not confusing which features are monad-specific and which stem from applicativefunctors is vitally important for a deeper understanding of monads. As anexample, the applicative functor interface of parser libraries can parsecontext-free languages (modulo hacks abusing open recursion), while the monadicinterface can parse context-sensitive grammars: Monads allow you to influencefurther processing by inspecting the result of your parse. To understand why,have a look at the type of(>>=). To understand why applicativefunctors by themselves are sufficient to track the current parsing position andexpress sequencing, have a look at theuu-parsinglib tutorial.

The exact differences are elaborated in even greater detail in Brent Yorgey'sexcellentTypeclassopedia.

Is the monadic interface just about ordering or sequencing?

No. What makes a monadic type sequential is the actual type, not the interface.Indeed, some monadic types arecommutative, like those for providingunique new abstract identifiers:

do fun' <- rename cxt fun   arg' <- rename cxt arg   return (Apply fun arg)
do arg' <- rename cxt arg   fun' <- rename cxt fun   return (Apply fun arg)

Each identifer is unique, so the order in which they're used is irrelevant.

But here's a closer look at what's meant by ordering. Consider an expressionlike

let x = a    y = bin  f x y

That gives the same result as

let y = b    x = ain  f x y

It doesn't matter what order we write the two bindings forx ory. But for doing I/O we'd like ordering. The monads interface allowsus to express:

do x <- getChar   y <- getChar   return (x, y)

and have it be different from

do y <- getChar   x <- getChar   return (x, y)

Unlike the first, the second example returns a pair of characters in theopposite order to which they were entered.

It might help to meditate about the difference between 'assignment' and'binding', right now.

However, just to spoil the enlightenment you just attained, there are monadictypes for which swapping the order of lines like this makes no difference: forexample,Reader a is also a commutative monadic type.

So while it is correct to say that the monadic interface can help to ordermonadic operations, it would be wrong to say that the monadic interface are amechanism for ordering those operations.

This notion of commutativity looks superficially very different from thefamiliar one in vanilla algebra wherea + b = b + a. It doesn't meanthat m >> n === n >> m - it won't hold hold in general foranynon-trivial monadic type, as for the most part

return 1 >> return 2 === return 2 =/= return 1 === return 2 >> return 1

This shouldn't be too surprising, though, as(>>) isn't the binaryoperation of a monoid. Thecategory-theoretic definitionof a commutative monadic type is rather more abstract.


You'restill here...alright, if you really have to know:

(Here's a list of introductory articlesabout continuations.;-)

See also

Retrieved from "https://wiki.haskell.org/index.php?title=What_a_Monad_is_not&oldid=67654"
Categories:

[8]ページ先頭

©2009-2026 Movatter.jp