Thursday, March 21, 2013

HASKELL MONAD TYPE CLASS

HASKELL MONAD TYPE CLASS

REVISED: Monday, February 12, 2024




Haskell Monad Type Class.

I.  HASKELL MONOID VERSUS MONAD TYPE CLASS

Monads are unavoidable, because they are the only way to do IO without violating referential transparency that given a function and an input value, you will always receive the same output. The essence of monads is composition.

As you study monads keep in mind it is no more necessary to understand monad theory to perform Haskell I/O than it is to understand group theory to do simple arithmetic. That said, the information below is for those of us who would like an introduction to monad theory with the objective of understanding monad theory.

A monad consists of a type constructor M and two operations, bind >>= and return. The return operation takes a value from a plain type and puts it into a monadic container using the constructor. The bind >>= operation performs the reverse process, extracting the original value from the container and passing it to the associated next function in the pipeline. This process effectively creates an action that chooses the next action based on the results of previous actions. Therefore, we should be able to determine our next action based on the results of previous actions.  The Haskell programming language is a functional language that makes heavy use of monads, and includes syntactic sugar to make monadic composition more convenient.  

(M t) -> (t -> M u) -> (M u)   -- Two common ways of describing a monad.
IO a → (a → IO b) → IO b

If M is the name of the monad and t is a data type, then M t is the corresponding type in the monad.

The unit function has the polymorphic type t → M t, which Haskell represents by return.

Binding operation of polymorphic type (M t) → (t → M u) → (M u), which Haskell represents by the infix operator >>= which is read as "bind"

As shown above Haskell has an operator >>= pronounced "bind" with type IO a → (a → IO b) → IO b. That is, the operand on the left is an I/O action that returns a value of type a; the operand on the right is a function that can pick an I/O action based on the value produced by the action on the left. The resulting combined action, when performed, performs the first action, then evaluates the function with the first action's return value, then performs the second action, and finally returns the second action's value.

For example:

Use your editor to save the following MonadPipeline.hs file:

main =
       putStrLn "What is your name?" >> 
       getLine >>= \name ->
       putStrLn ("Nice to meet you, " ++ name ++ "!")

As shown below, load the above MonadPipeline.hs file into GHCi:

Prelude>  :load MonadPipeline.hs
[1 of 1] Compiling Main             ( MonadPipeline.hs, interpreted )
Ok, modules loaded: Main.
Prelude>

Prelude>  main
What is your name?
Elcric
Nice to meet you, Elcric!
Prelude>  

The pipeline structure of the bind >>= operator ensures that the getLine and putStrLn operations get evaluated only once and in the given order, so that the side-effects of extracting text from the input stream and writing to the output stream are correctly handled in the functional pipeline.

A. FUNCTOR

Every monad is a functor which transforms one category into another category.

class Functor f where
   fmap :: (a -> b) -> f a -> f b

Think of a functor as a type of container where we are permitted to apply a single function to every object in the container.

If f is a functor, and we are given a function of type (a -> b), and a container of type (f a), we can get a new container of type (f b).

B. MONOID

Given

  is for every.
  is an element of.
  is a function.
  is there exists.
:   is such that.
is defined to be.

then

a Monoid is a function () that satisfies the following:

1. The Set (S) is closed under the binary function ().

∀ a,b ∈ S: ab ∈ S

2. The binary function is associative.

∀ a,b,c ∈ S: (ab)c = a(bc)

3. e is the identity element.

∃ e∈S: ∀ a∈S: ea = ae = a

C. MONAD LAWS

As shown below the three monad laws can be described in many different ways. Each author seems to have their own favorite descriptions.

Four commonly used descriptions of the three laws that monads must obey are color coded below for comparison:

1. Left Identity

return a >>= f ≡ f a

return >=> f == f

id . f  ==  f

return x >>= f ==  f x

2. Right Identity

m >>= return ≡ m

f >=> return == f

f . id ==  f

mv >>= return ==  mv

3. Associativity

(m >>= f) >>= g ≡ m >>= (\x -> f x >>= g)

(f >=> g) >=> h == f >=> (g >=> h)

(f . g) . h == f . (g . h)

(mv >>= f) >>= g == mv >>= (\x -> (f x >>= g))

1. Left Identity

return a >>= f ≡ f a

2. Right Identity

m >>= return ≡ m

3. Associativity

(m >>= f) >>= g ≡ m >>= (\x -> f x >>= g)

1. Left Identity

return >=> f == f

2. Right Identity

f >=> return == f

3. Associativity

(f >=> g) >=> h == f >=> (g >=> h)

1. Left Identity

id . f  ==  f

2. Right Identity

f . id ==  f

3. Associativity

(f . g) . h == f . (g . h)

1. Left Identity

return x >>= f ==  f x

2. Right Identity

mv >>= return ==  mv

3. Associativity

(mv >>= f) >>= g == mv >>= (\x -> (f x >>= g))

Monad is a type class. To be an instance of the Monad type class, you must provide the functions (>>=) and return. The function (>>) will be derived from (>>=). >>= is called an argument in the monadic world.

Prelude> :type (>>)
(>>) :: Monad m => m a -> m b -> m b
Prelude>

Prelude> :type (>>=)
(>>=) :: Monad m => m a -> (a -> m b) -> m b
Prelude>

Prelude> :type return
return :: Monad m => a -> m a
Prelude>

m stands for Monad.

Everything before the => symbol is called a class constraint.

Using the same symbol or name for different operations is called overloading. A type that contains one or more class constraints is called ad hoc polymorphism, better known as overloaded. In Haskell, type classes provide a structured way to control ad hoc polymorphism, or overloading.

D. MONAD

NO SIDE EFFECTS

The following identity Functor is also a  monad, a monad with no side effects.

data I a = I a
instance Functor I where
    fmap f (I x) = I (f x)

The identity function takes one argument and returns that argument.

Composing functions with no side effects:

g :: a -> b  -- Function g has input type a and output type b.
f  :: b -> c  -- Function f has input type b and output type c.

f o g :: a -> c

Their composition f o g is defined as first the application of function g to a variable of type a and then the application of function f to the output of g a variable of type b.

SIDE EFFECTS

Monads make possible the composition of functions with side effects, we have to use bind instead of normal function composition.

Given M is a monad, we want to compose the following two functions.

g :: a -> M b
f  :: b -> M c

The output of g is of type a ->  M b and f is of type b -> M c. Therefore, >>= is of type 

M b -> (b -> M c) -> M c

f composed with g is taking the output of g and passing it to f.

g  >>= f

>>= takes the output of which is of type M b and also takes the function f
which is of type b -> M c and produces the output of f which is of type M c.

M b -> (b -> M c) -> M c

which is the type of  >>= bind.

By providing the definition of the function

M b -> (b -> M c) -> M c

we provide the way for the functions

g :: a -> M b
f  :: b -> M c

to be composed.

II. CONCLUSION

In this tutorial, you have received an introduction to the Haskell monad type class.

III. REFERENCES

Bird, R. (2015). Thinking Functionally with Haskell. Cambridge, England: Cambridge University Press.

Davie, A. (1992). Introduction to Functional Programming Systems Using Haskell. Cambridge, England: Cambridge University Press.

Goerzen, J. & O'Sullivan, B. &  Stewart, D. (2008). Real World Haskell. Sebastopol, CA: O'Reilly Media, Inc.

Hutton, G. (2007). Programming in Haskell. New York: Cambridge University Press.

Lipovača, M. (2011). Learn You a Haskell for Great Good!: A Beginner's Guide. San Francisco, CA: No Starch Press, Inc.

Thompson, S. (2011). The Craft of Functional Programming. Edinburgh Gate, Harlow, England: Pearson Education Limited.