I'm reading the instance of Applicative for functions,
and encountered a line
instance Applicative ((->) r) where
pure x = (\_ -> x)
f <*> g = \x -> f x (g x)
I understand the syntax, but don't understand the meaning of the second line.
My understanding is: partially applied function ((->) r) gets a value and wraps that value into the context, which contains function that always returns that value.
Why doesn't it just compute the result by applying partially applied function to that x, and only after that it would store the result in Applicative context?
The signatures of pure and (<*>) for the function instance are
pure :: a -> ((->) r a)
(<*>) :: ((->) r (a -> b)) -> ((->) r a) -> ((->) r b)
Writing the (->) as infix operator gives
pure :: a -> (r -> a)
(<*>) :: (r -> (a -> b)) -> (r -> a) -> (r -> a)
So pure is a function that takes a parameter of type a and returns a function that takes a parameter of type r and returns a value of type a.
Since we can't know the type of r as we write pure, we can only give a function that return the parameter given to pure.
Related
a line from FileIO.hs in Functional Programming Course exercise
getFile :: FilePath -> IO (FilePath, Chars)
getFile = lift2 (<$>) (,) readFile
According to its type signature, getFile returns IO ( FilePath, Chars), which means a tuple of filename and its content.
But I just can't figure out why it turns that way.
Why does FilePath turn out unchanged in the left, and readFile filename filled in the right?
Is (,) an Applicative instance too? (,) is not an IO, so what did lift2 lift?
And, is there a way to derive those type signatures and get proved?
The syntax I know is that a function follows by its arguments, and it eats one argument on its right hand and becomes a new function. But when it comes to code like that, it looks just like a magic cube to me...
Thank you for helping me out!
Ps. Extra Information as follows
instance Functor IO where
(<$>) =
P.fmap
lift2 ::
Applicative f =>
(a -> b -> c)
-> f a
-> f b
-> f c
lift2 f a b =
f <$> a <*> b
getFiles :: List FilePath -> IO (List (FilePath, Chars))
getFiles = sequence . (<$>) getFile
Let's look at
lift2 (<$>) (,) readFile
This is indeed straightforward function application:
((lift2 (<$>)) (,)) readFile
(or lift2 being applied to three arguments).
The types involved (with uniquely renamed type variables to reduce confusion) are:
lift2 :: (Applicative f) => (a -> b -> c) -> f a -> f b -> f c
(<$>) :: (Functor g) => (j -> k) -> g j -> g k
(,) :: m -> n -> (m, n)
readFile :: FilePath -> IO Chars
The first thing in our expression is applying lift2 to (<$>). That means we need to unify a -> b -> c (type of lift2's first argument) and (Functor g) => (j -> k) -> g j -> g k (type of <$>) somehow.
That is:
a -> b -> c = (j -> k) -> g j -> g k
-- where g is a Functor
a = j -> k
b = g j
c = g k
This works out. The result type is
f a -> f b -> f c
-- where f is an Applicative
which is
f (j -> k) -> f (g j) -> f (g k)
Now this expression (lift2 (<$>)) is applied to (,). Again we have to make the types line up:
f (j -> k) = m -> n -> (m, n)
Here we make use of the property that -> is right associative (i.e. a -> b -> c means a -> (b -> c)) and that we can use (curried) prefix notation in types (i.e. a -> b is the same as (->) a b, which is the same as ((->) a) b).
f (j -> k) = ((->) m) (n -> (m, n))
f = (->) m
j = n
k = (m, n)
This also works out. The result type is
f (g j) -> f (g k)
which (after substituting) becomes
((->) m) (g n) -> ((->) m) (g (m, n))
(m -> g n) -> (m -> g (m, n))
This expression (lift2 (<$>) (,)) is applied to readFile. Again, making the types line up:
m -> g n = FilePath -> IO Chars
m = FilePath
g = IO
n = Chars
And substituting into the result type:
m -> g (m, n)
FilePath -> IO (FilePath, Chars)
This is the type of the whole lift2 (<$>) (,) readFile expression. As expected, it matches the declaration of getFile :: FilePath -> IO (FilePath, Chars).
However, we still need to verify that our class constraints (Functor g, Applicative f) are resolved.
g is IO, which is indeed a Functor (as well as Applicative and Monad). There are no big surprises here.
f is more interesting: f = (->) m, so we need to look for an Applicative instance for (->) m. Such an instance does in fact exist, and its definition contains the answer to what getFile actually does.
We can derive what the instance must look like by just looking at the type of lift2 (as used in getFile):
lift2 :: (Applicative f) => (a -> b -> c) -> f a -> f b -> f c
lift2 :: (a -> b -> c) -> ((->) m) a -> ((->) m) b -> ((->) m) c
lift2 :: (a -> b -> c) -> (m -> a) -> (m -> b) -> (m -> c)
lift2 :: (a -> b -> c) -> (m -> a) -> (m -> b) -> m -> c
I.e. lift2 takes
a function that combines an a and a b into a c,
a function that transforms an m into an a,
a function that transforms an m into a b,
and an m,
and produces a c.
The only way it can do that is by passing the m into the second and third functions and combining their results using the first function:
lift2 f g h x = f (g x) (h x)
If we inline this definition in getFile, we get
getFile = lift2 (<$>) (,) readFile
getFile = \x -> (<$>) ((,) x) (readFile x)
getFile = \x -> (,) x <$> readFile x
Excercise for the reader:
lift2 is actually defined in terms of <$> and <*>. What are the types of <$> and <*> in the Applicative instance of (->) m? What must their definition look like?
I'm trying to improve my understanding of Applicatives and Monads by implementing their function instances in Javascript. My knowledge of Haskell is limited and I hope that my question makes sense at all.
Here are my implementations of fmap, <*> and >>= for the Functor, Applicative and Monad typeclasses in Javascript:
const fmap = f => g => x => f(g(x)); // B combinator
const apply = f => g => x => f(x) (g(x)); // S combinator
const bind = f => g => x => g(f(x)) (x); // ?
I am not sure whether bind is the correct translation of the Haskell implementation:
(>>=) :: (r -> a) -> (a -> (r -> b)) -> r -> b
instance Monad ((->) r) where
f >>= k = \ r -> k (f r) r
Provided that bind is correct, how is it interpreted? I know that an Applicative can sequence effectful computations. I also know that a Monad in addition allows you to determine a next effect according to the result of a previous one.
I can see the sequences (eager evaluation order in Javascript):
apply: f(x) ... g(x) ... lambda(result of g) ... result of lambda
bind: f(x) ... g(result of f) ... lambda(x) ... result of lambda
However, the bind function looks pretty weird. Why are f and g nested the other way around? How is the specific Monad behavior (determines a next effect according to a previous one) reflected in this implementation? Actually g(f(x)) (x) looks like a function composition with flipped arguments, where g is a binary function.
When I apply apply/bind with an unary and a binary function, they yield the same result. This doesn't make much sense.
A few footnotes to Lee's answer:
However, the bind function looks pretty weird. Why are f and g
nested the other way around?
Because bind is backwards. Compare (>>=) and its flipped version (=<<):
(>>=) :: Monad m => m a -> (a -> m b) -> m b
(=<<) :: Monad m => (a -> m b) -> m a -> m b
Or, in your specific example:
(>>=) :: (r -> a) -> (a -> (r -> b)) -> (r -> b)
(=<<) :: (a -> (r -> b)) -> (r -> a) -> (r -> b)
While in practice we tend to use (>>=) more often than (=<<) (because of how (>>=), syntactically speaking, lends itself well to the kind of pipeline monads are often used to build), from a theoretical point of view (=<<) is the most natural way of writing it. In particular, the parallels and differences with fmap/(<$>) and (<*>) are much more obvious:
(<$>) :: Functor f => (a -> b) -> f a -> f b
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
(=<<) :: Monad f => (a -> f b) -> f a -> f b
When I apply apply/bind with an unary and a binary function, they yield the same result. This doesn't make much sense.
That is an accidental fact about the function instances. Let's put the specialised signatures side by side:
(<*>) :: (r -> (a -> b)) -> (r -> a) -> (r -> b)
(=<<) :: (a -> (r -> b)) -> (r -> a) -> (r -> b)
Monad goes beyond Applicative by providing the means to determine the next effect according to previous results (as opposed to "previous effect" -- Applicative can do that already). The effect, in this case, consists of a function that generates values given an argument of type r. Now, since functions with multiple arguments (i.e. functions that return functions) can be flipped, it happens that there is no significant difference between (r -> (a -> b)) and (a -> (r -> b)) (flip can trivially change one into the other), which makes the Monad instance for (->) r entirely equivalent to the Applicative one.
The values in the monad instance for functions have type r -> a for some fixed type r. The function (a -> (r -> b)) given to (>>=) allows you to choose the next function to return given the result from the current value (a function r -> a). f r has type a and k (f r) has type r -> b which is the next function to apply.
In your code g(f(x)) is therefore a function which expects a single argument of type r. The caller of bind can choose this function based on the value returned by the previous function e.g.
var inc = x => x + 1;
var f = bind(inc)(function(i) {
if(i <= 5) { return x => x * 2; }
else { return x => x * 3; }
});
The function will be given x as an input and can choose the next stage in the computation based on the result of inc(x) e.g.
f(2) //4;
f(5) //15;
In the following instance of Monad:
instance Monad ((->) r) where
return = const
f >>= k = \ r -> k (f r) r
Is this forcing k to be a function of two parameters? And if so, why would you want to pass (f r) AND r to k?
Is this forcing k to be a function of two parameters?
Yes. Looking at the definition of Monad, we have
class Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
Substituting (->) r for m, we have
return :: a -> (->) r a
(>>=) :: (->) r a -> (a -> (->) r b) -> (->) r b
Now, (->) r a is just a weird syntax for r -> a, and similarly for the other cases, so we get
return :: a -> r -> a
(>>=) :: (r -> a) -> (a -> r -> b) -> r -> b
So we can see that indeed the second argument to >>= must be a function of (at least) two arguments.
Why? Because a function of two arguments is just a function taking one argument and returning a function of one argument, while the second argument to >>= should be a function taking one argument and returning a value of the monad's type constructor; for the function monad, this value will be a function. Hence the second argument to >>= will be a function of two arguments.
[W]hy would you want to pass (f r) AND r to k?
Partly because it makes the (->) r type fit the uniform structure of a Monad, which is useful for lots of reasons.
Partly k doesn't know which function f you're using. That means that, from k's perspective, the two arguments f r and r really are independent --- k can't calculate one from the other.
Consider this function:
-- | 'f' takes two numbers and adds them together
f :: (->) (Int, Int) Int
f = fst >>= \ n0 -> snd >>= \ n1 -> return (n0 + n1)
The function \ n0 -> snd >>= \ n1 -> return (n0 + n1) doesn't care where its argument comes from, or in particular that its argument is the first component of the input. So it needs both the argument n0 and the full input.
I'm new to Haskell, here get in trouble with <*> :
((==) <*>) :: Eq a => (a -> a) -> a -> Bool
How can I understand this and how it can be deduced?
Disclaimer: That's not idiomatic Haskell code.
The first thing that takes precedence is the "operator section" of <*>. When you see an operator only applied to one argument that's called a section. Here's an example of a more common operator section:
(1 +) :: Int -> Int
That's a function that partially applies + to 1, leaving room for one last argument. It's equivalent to:
\x -> 1 + x
So in your code sample the <*> is partially applied to (==), so we'll expand that out to:
((==) <*>)
= \g -> (==) <*> g
Next off you need to understand what the <*> is doing. This is a member of the Applicative type class:
class (Functor f) => Applicative f where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
This means that <*> is overloaded to work on any type that implements Applicative. One instance of the Applicative type is ((->) r):
instance Applicative ((->) r) where
pure :: a -> ((->) r) a
(<*>) :: (->) r (a -> b) -> (->) r a -> (->) r b
The parentheses around the (->) mean that is being used in prefix form (which is necessary for syntactic reasons when defining class instances like this one). If you expand it out to infix form you get:
instance Applicative ((->) r) where
pure :: a -> r -> a
(<*>) :: (r -> a -> b) -> (r -> a) -> (r -> b)
In your specific example, the first argument of <*> is the (==) operator, which has the following type:
(==) :: Eq e => e -> e -> Bool
Therefore, if we pass it to the (<*>) the compiler can deduce more about the types of r, a, and b in the signature for (<*>):
(<*>) :: (r -> a -> b ) -> (r -> a) -> (r -> b)
(==) :: Eq e => e -> e -> Bool
| | |
| | +-> `b` must be `Bool`
| |
| +------> `a` must be `e`
|
+-----------> `r` must also be `e`
So when we supply (==) as the first argument of (<*>) we get this inferred type:
((==) <*>) :: Eq e => (e -> e) -> (e -> Bool)
You can leave off the right parentheses because (->) is right-associative, and change e to a to give the final signature you got:
((==) <*>) :: Eq a => (a -> a) -> a -> Bool
But what is this actually doing? To understand that we need to see how (<*>) is defined for the Applicative instance of ((->) r):
(f <*> g) r = f r (g r)
If we replace f with (==) we get:
((==) <*> g) r = (==) r (g r)
When we surround (==) with parentheses, that means we are using it in prefix notation. This means that if we remove the parentheses and change it back to infix notation we get:
((==) <*> g) r = r == (g r)
This is equivalent to:
((==) <*>) = \g r -> r == g r
So that means that your function takes two parameters: g and r, and then sees if r equals g r.
At different questions I've found hints in comments concerning using the (->) instance of Monads e.g. for realizing point-free style.
As for me, this is a little too abstract. Ok, I've seen Arrow instances on (->) and it seems to me, that (->) can be used in instance notations but not in type declarations (that would alone be stuff for another question).
Has anyone examples using (->) as instance of Monad? Or a good link?
Sorry if this question may already have been discussed here, but searching for "(->) Monad instance" gives you many many hits as you can imagine ... since nearly every question about Haskell somewhere involves (->) or "Monad".
For a given type r, the function of type r -> a can be thought of as a computation delivering an a using an environment typed r. Given two functions r -> a and a -> (r -> b), it's easy to imagine that one can compose these when given an environment (again, of type r).
But wait! That's exactly what monads are about!
So we can create an instance of Monad for (->) r that implements f >>= g by passing the r to both f and g. This is what the Monad instance for (->) r does.
To actually access the environment, you can use id :: r -> r, which you can now think of as a computation running in an environment r and delivering an r. To create local sub-environments, you can use the following:
inLocalEnvironment :: (r -> r) -> (r -> a) -> (r -> a)
inLocalEnvironment xform f = \env -> f (xform env)
This pattern of having an environment passed to computations that can then query it and modify it locally is useful for not just the (->) r monad, which is why it is abstracted into the MonadReader class, using much more sensible names than what I've used here:
http://hackage.haskell.org/packages/archive/mtl/2.0.1.0/doc/html/Control-Monad-Reader-Class.html
Basically, it has two instances: (->) r that we've seen here, and ReaderT r m, which is just a newtype wrapper around r -> m a, so it's the same thing as the (->) r monad I've described here, except it delivers computations in some other, transformed monad.
To define a monad for (->) r, we need two operations, return and (>>=), subject to three laws:
instance Monad ((->) r) where
If we look at the signature of return for (->) r
return :: a -> r -> a
we can see its just the constant function, which ignores its second argument.
return a r = a
Or alternately,
return = const
To build (>>=), if we specialize its type signature with the monad (->) r,
(>>=) :: (r -> a) -> (a -> r -> b) -> r -> b
there is really only one possible definition.
(>>=) x y z = y (x z) z
Using this monad is like passing along an extra argument r to every function. You might use this for configuration, or to pass options way down deep into the bowels of your program.
We can check that it is a monad, by verifying the three monad laws:
1. return a >>= f = f a
return a >>= f
= (\b -> a) >>= f -- by definition of return
= (\x y z -> y (x z) z) (\b -> a) f -- by definition of (>>=)
= (\y z -> y ((\b -> a) z) z) f -- beta reduction
= (\z -> f ((\b -> a) z) z) -- beta reduction
= (\z -> f a z) -- beta reduction
= f a -- eta reduction
2. m >>= return = m
m >>= return
= (\x y z -> y (x z) z) m return -- definition of (>>=)
= (\y z -> y (m z) z) return -- beta reduction
= (\z -> return (m z) z) -- beta reduction
= (\z -> const (m z) z) -- definition of return
= (\z -> m z) -- definition of const
= m -- eta reduction
The final monad law:
3. (m >>= f) >>= g ≡ m >>= (\x -> f x >>= g)
follows by similar, easy equational reasoning.
We can define a number of other classes for ((->) r) as well, such as Functor,
instance Functor ((->) r) where
and if we look at the signature of
-- fmap :: (a -> b) -> (r -> a) -> r -> b
we can see that its just composition!
fmap = (.)
Similarly we can make an instance of Applicative
instance Applicative ((->) r) where
-- pure :: a -> r -> a
pure = const
-- (<*>) :: (r -> a -> b) -> (r -> a) -> r -> b
(<*>) g f r = g r (f r)
What is nice about having these instances is they let you employ all of the Monad and Applicative combinators when manipulating functions.
There are plenty of instances of classes involving (->), for instance, you could hand-write the instance of Monoid for (b -> a), given a Monoid on a as:
enter code here
instance Monoid a => Monoid (b -> a) where
-- mempty :: Monoid a => b -> a
mempty _ = mempty
-- mappend :: Monoid a => (b -> a) -> (b -> a) -> b -> a
mappend f g b = f b `mappend` g b
but given the Monad/Applicative instance, you can also define this instance with
instance Monoid a => Monoid (r -> a) where
mempty = pure mempty
mappend = liftA2 mappend
using the Applicative instance for (->) r or with
instance Monoid a => Monoid (r -> a) where
mempty = return mempty
mappend = liftM2 mappend
using the Monad instance for (->) r.
Here the savings are minimal, but, for instance the #pl tool for generating point-free code, which is provided by lambdabot on the #haskell IRC channel abuses these instances quite a bit.