I am learning about monads from the book 'Learn You a Haskell for Great Good!' by Miran Lipovaca. I am trying to understand the associativity law for monads. Essentially, the law states that when you have a chain of monadic function applications with >>=, it shouldn't matter how they're nested.
The following code enables one to pass the result of a function of type a -> m b to a function of type b -> m c:
(<=<) :: (Monad m) => (b -> m c) -> (a -> m b) -> (a -> m c)
f <=< g = (\x -> g x >>= f)
However, for the example below:
ghci> let f x = [x, -x]
ghci> let g x = [x*3, x*2]
ghci> let h = f <=< g
ghci> h 3
[9, -9, 6, -6]
Are f x and g x both functions? It seems to be that they are lists with different values of x and not functions. How does the line let h = f <=< g work in the above code? f and g have to be functions since they are used with <=< but I am not sure what they are.
This is ordinary function definition syntax. We are defining a new function
f, by writing down what it would produce when applied to a hypothetical valuex.let(whether as a statement or alet ... in ...expression) just introduces a block where you can make definitions, much likewhere. The definitions themselves use the same syntax as global ones do.If you know how to define functions by writing e.g.
plusOne n = n + 1in a file, then this syntax is exactly the same (if you don't know how to do that, then I'd suggest reading through some introductory tutorials on fundamental Haskell syntax before you try to understand monadic function composition).So after those definitions
fandgare functions.f xandg xdon't really make sense, since you don't have anxin scope to apply them to.If you did have such a value in scope, then
f xwould be an expression that evaluates to a list, which involves calling the functionf. It still wouldn't be true to say thatf xorg xare functions.So now it should be clear that
let h = f <=< gis defining a new valuehby applying the<=<operator tofandg.