How can I change following code so that each element in Maybe monoid element takes also two arguments (so it would become "double" reader applicative)?
g :: (Monoid a, IsString a) => [Maybe a] -> Maybe a
g = foldr (<>) (Just "")
So that result would be of type:
g2 :: (Monoid a, IsString a) => [b -> c -> Maybe a] -> b -> c -> Maybe a
I guess I could lift <> twice:
> :t (liftA2 $ liftA2 (<>))
(liftA2 $ liftA2 (<>))
:: (Monoid c, Applicative f1, Applicative f) =>
f (f1 c) -> f (f1 c) -> f (f1 c)
But I'm stuck trying to compose it with foldr to get the type signature I want.
This is how I would do it
g2 x y = g $ ($ y) <$> ($ x) <$> theList
Related
In Haskell, the Functor has a function fmap which the type of it is:
ghci> :t fmap
fmap :: Functor f => (a -> b) -> f a -> f b
This makes sense to me that fmap lifts a function from the type of a -> b to f a -> f b.
Then I am curious about what is the type of fmap fmap, so I tried and got something weird to me:
ghci> :t fmap fmap
fmap fmap
:: (Functor f1, Functor f2) => f1 (a -> b) -> f1 (f2 a -> f2 b)
Hmm, this type is somewhat complicate, but I can explain it by replacing a with a -> b and b with f2 a -> f2 b.
Then, I wanted to one step further:
fmap fmap fmap
:: (Functor f1, Functor f2) => (a -> b) -> f1 (f2 a) -> f1 (f2 b)
Oh, wait! Things go to be fun when putting 3 fmap together. How to explain this?
Could someone help to explain how could I derive the type of fmap fmap fmap?
For clarity, let's introduce
fmapA, fmapB, fmapC :: Functor f => (a -> b) -> f a -> f b
fmapA = fmapB = fmapC = fmap
and consider
fmapA fmapB fmapC :: ?
Forget about fmapB for a bit, start with fmapA _ fmapC. You're treating fmapC on the right as a container here, over which you map something. Does that make sense? Well, look at the type in non-infix form. Recall that x -> y -> z is the same as x -> (y -> z), and p -> q is the same as ((->) p) q, thus
fmapC :: ((->) p) q where {p ~ (a->b), q ~ (f a->f b)}
To use this as a container type, the f in fmapA's signature needs to unify with (->) p. That's the function functor. So, despite having three polymorphic fmaps here, one of the functors is already predetermined by the expression. Therefore, it would be better to immediately resolve the polymorphism that only makes it more difficult to understand, and replace it with the definition of that particular functor instance, which turns out to be rather simple:
instance Functor ((->) a) where
fmap = (.)
So, that reduces our expression to (.) fmapB fmapC – or, as it's preferrably written,
fmapB . fmapC
Which is a far more sensible thing to write in actual code, and has been discussed previously on StackOverflow.
{-# Language BlockArguments #-}
{-# Language ScopedTypeVariables #-}
{-# Language TypeApplications #-}
fffmap
:: forall f g a b. ()
=> Functor f
=> Functor g
=> (a -> b)
-> (f (g a) -> f (g b))
fffmap = fmap fmap fmap
A polymorphic function takes a type as an argument. The forall. quantifiee is invisible and implicitly solved by unification but we can explicitly instantiate it with a type application #...
I use block arguments which allows me to write fmap fmap fmap as
do fmap
do fmap
do fmap
just to make it clearer. This is how they are actually instantiated:
fffmap
:: forall f g a b. ()
=> Functor f
=> Functor g
=> (a -> b)
-> (f (g a) -> f (g b))
fffmap =
do fmap #((->) (a -> b)) #(g a -> g b) #(f (g a) -> f (g b))
do fmap #f #(g a) #(g b)
do fmap #g #a #b
The first fmap = (.) is instantiated to the reader monad (.. ->), no wonder you find it complicated. If you look at the type of f1, it IS complicated.
fffmap
:: forall f g a b.
Functor f
=> Functor g
=> (a -> b)
-> (f (g a) -> f (g b))
fffmap = f1 f2 f3 where
f1 :: ((g a -> g b) -> f (g a) -> f (g b)) -> ((a -> b) -> g a -> g b) -> (a -> b) -> f (g a) -> f (g b)
f1 = fmap
f2 :: (g a -> g b) -> (f (g a) -> f (g b))
f2 = fmap
f3 :: (a -> b) -> (g a -> g b)
f3 = fmap
class Applicative f => Monad f where
return :: a -> f a
(>>=) :: f a -> (a -> f b) -> f b
(<*>) can be derived from pure and (>>=):
fs <*> as =
fs >>= (\f -> as >>= (\a -> pure (f a)))
For the line
fs >>= (\f -> as >>= (\a -> pure (f a)))
I am confused by the usage of >>=. I think it takes a functor f a and a function, then return another functor f b. But in this expression, I feel lost.
Lets start with the type we're implementing:
(<*>) :: Monad f => f (a -> b) -> f a -> f b
(The normal type of <*> of course has an Applicative constraint, but here we're trying to use Monad to implement Applicative)
So in fs <*> as = _, fs is an "f of functions" (f (a -> b)), and as is an "f of as".
We'll start by binding fs:
(<*>) :: Monad f => f ( a -> b) -> f a -> f b
fs <*> as
= fs >>= _
If you actually compile that, GHC will tell us what type the hole (_) has:
foo.hs:4:12: warning: [-Wtyped-holes]
• Found hole: _ :: (a -> b) -> f b
Where: ‘a’, ‘f’, ‘b’ are rigid type variables bound by
the type signature for:
(Main.<*>) :: forall (f :: * -> *) a b.
Monad f =>
f (a -> b) -> f a -> f b
at foo.hs:2:1-45
That makes sense. Monad's >>= takes an f a on the left and a function a -> f b on the right, so by binding an f (a -> b) on the left the function on the right gets to receive an (a -> b) function "extracted" from fs. And provided we can write a function that can use that to return an f b, then the whole bind expression will return the f b we need to meet the type signature for <*>.
So it'll look like:
(<*>) :: Monad f => f ( a -> b) -> f a -> f b
fs <*> as
= fs >>= (\f -> _)
What can we do there? We've got f :: a -> b, and we've still got as :: f a, and we need to make an f b. If you're used to Functor that's obvious; just fmap f as. Monad implies Functor, so this does in fact work:
(<*>) :: Monad f => f ( a -> b) -> f a -> f b
fs <*> as
= fs >>= (\f -> fmap f as)
It's also, I think, a much easier way to understand the way Applicative can be implemented generically using the facilities from Monad.
So why is your example written using another >>= and pure instead of just fmap? It's kind of harkening back to the days when Monad did not have Applicative and Functor as superclasses. Monad always "morally" implied both of these (since you can implement Applicative and Functor using only the features of Monad), but Haskell didn't always require there to be these instances, which leads to books, tutorials, blog posts, etc explaining how to implement these using only Monad. The example line given is simply inlining the definition of fmap in terms of >>= and pure (return)1.
I'll continue to unpack as if we didn't have fmap, so that it leads to the version you're confused by.
If we're not going to use fmap to combine f :: a -> b and as :: f a, then we'll need to bind as so that we have an expression of type a to apply f to:
(<*>) :: Monad f => f ( a -> b) -> f a -> f b
fs <*> as
= fs >>= (\f -> as >>= (\a -> _))
Inside that hole we need to make an f b, and we have f :: a -> b and a :: a. f a gives us a b, so we'll need to call pure to turn that into an f b:
(<*>) :: Monad f => f ( a -> b) -> f a -> f b
fs <*> as
= fs >>= (\f -> as >>= (\a -> pure (f a)))
So that's what this line is doing.
Binding fs :: f (a -> b) to get access to an f :: a -> b
Inside the function that has access to f it's binding as to get access to a :: a
Inside the function that has access to a (which is still inside the function that has access to f as well), call f a to make a b, and call pure on the result to make it an f b
1 You can implement fmap using >>= and pure as fmap f xs = xs >>= (\x -> pure (f x)), which is also fmap f xs = xs >>= pure . f. Hopefully you can see that the inner bind of your example is simply inlining the first version.
Applicative is a Functor. Monad is also a Functor. We can see the "Functorial" values as standing for computations of their "contained" ⁄ produced pure values (like IO a, Maybe a, [] a, etc.), as being the allegories of ⁄ metaphors for the various kinds of computations.
Functors describe ⁄ denote notions ⁄ types of computations, and Functorial values are reified computations which are "run" ⁄ interpreted in a separate step which is thus akin to that famous additional indirection step by adding which, allegedly, any computational problem can be solved.
Both fs and as are your Functorial values, and bind ((>>=), or in do notation <-) "gets" the carried values "in" the functor. Bind though belongs to Monad.
What we can implement in Monad with (using return as just a synonym for pure)
do { f <- fs ; -- fs >>= ( \ f -> -- fs :: F (a -> b) -- f :: a -> b
a <- as ; -- as >>= ( \ a -> -- as :: F a -- a :: a
return (f a) -- return (f a) ) ) -- f a :: b
} -- :: F b
( or, with MonadComprehensions,
[ f a | f <- fs, a <- as ]
), we get from the Applicative's <*> which expresses the same computation combination, but without the full power of Monad. The difference is, with Applicative as is not dependent on the value f there, "produced by" the computation denoted by fs. Monadic Functors allow such dependency, with
[ bar x y | x <- xs, y <- foo x ]
but Applicative Functors forbid it.
With Applicative all the "computations" (like fs or as) must be known "in advance"; with Monad they can be calculated -- purely -- based on the results of the previous "computation steps" (like foo x is doing: for (each) value x that the computation xs will produce, new computation foo x will be (purely) calculated, the computation that will produce (some) y(s) in its turn).
If you want to see how the types are aligned in the >>= expressions, here's your expression with its subexpressions named, so they can be annotated with their types,
exp = fs >>= g -- fs >>=
where g f = xs >>= h -- (\ f -> xs >>=
where h x = return (f x) -- ( \ x -> pure (f x) ) )
x :: a
f :: a -> b
f x :: b
return (f x) :: F b
h :: a -> F b -- (>>=) :: F a -> (a -> F b) -> F b
xs :: F a -- xs h
-- <-----
xs >>= h :: F b
g f :: F b
g :: (a -> b) -> F b -- (>>=) :: F (a->b) -> ((a->b) -> F b) -> F b
fs :: F (a -> b) -- fs g
-- <----------
fs >>= g :: F b
exp :: F b
and the types of the two (>>=) applications fit:
(fs :: F (a -> b)) >>= (g :: (a -> b) -> F b)) :: F b
(xs :: F a ) >>= (h :: (a -> F b)) :: F b
Thus, the overall type is indeed
foo :: F (a -> b) -> F a -> F b
foo fs xs = fs >>= g -- foo = (<*>)
where g f = xs >>= h
where h x = return (f x)
In the end, we can see monadic bind as an implementation of do, and treat the do notation
do {
abstractly, axiomatically, as consisting of the lines of the form
a <- F a ;
b <- F b ;
......
n <- F n ;
return (foo a b .... n)
}
(with a, F b, etc. denoting values of the corresponding types), such that it describes the overall combined computation of the type F t, where foo :: a -> b -> ... -> n -> t. And when none of the <-'s right-hand side's expressions is dependent on no preceding left-hand side's variable, it's not essentially Monadic, but just an Applicative computation that this do block is describing.
Because of the Monad laws it is enough to define the meaning of do blocks with just two <- lines. For Functors, just one <- line is allowed ( fmap f xs = do { x <- xs; return (f x) }).
Thus, Functors/Applicative Functors/Monads are EDSLs, embedded domain-specific languages, because the computation-descriptions are themselves values of our language (those to the right of the arrows in do notation).
Lastly, a types mandala for you:
T a
T (a -> b)
(a -> T b)
-------------------
T (T b)
-------------------
T b
This contains three in one:
F a A a M a
a -> b A (a -> b) a -> M b
-------------- -------------- -----------------
F b A b M b
You can define (<*>) in terms of (>>=) and return because all monads are applicative functors. You can read more about this in the Functor-Applicative-Monad Proposal. In particular, pure = return and (<*>) = ap is the shortest way to achieve an Applicative definition given an existing Monad definition.
See the type signatures for (<*>), ap and (>>=):
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
ap :: Monad m => m (a -> b) -> m a -> m b
(>>=) :: Monad m => m a -> (a -> m b) -> m b
The type signature for (<*>) and ap are nearly equivalent. Since ap is written using do-notation, it is equivalent to some use of (>>=). I'm not sure this helps, but I find the definition of ap readable. Here's a rewrite:
ap m1 m2 = do { x1 <- m1; x2 <- m2; return (x1 x2) }
≡ ap m1 m2 = do
x1 <- m1
x2 <- m2
return (x1 x2)
≡ ap m1 m2 =
m1 >>= \x1 ->
m2 >>= \x2 ->
return (x1 x2)
≡ ap m1 m2 = m1 >>= \x1 -> m2 >>= \x2 -> return (x1 x2)
≡ ap mf ma = mf >>= (\f -> ma >>= (\a -> pure (f a)))
Which is your definition. You could show that this definition upholds the applicative functor laws, since not everything defined in terms of (>>=) and return does that.
fmap.fmap allows us to go "two layers deep" into a functor:
fmap.fmap :: (a -> b) -> f (g a) -> f (g b)
Is this also possible for applicative functors? Let's say I wanted to combine Just (+5) and [1,2,3] by using their applicative properties. I can think of an obvious way to do it, but it doesn't seem that trivial to me.
(<*>).(<*>) doesn't a have a conclusive type signature:
((<*>).(<*>)) :: (a1 -> a2 -> b) -> ((a1 -> a2) -> a1) -> (a1 -> a2) -> b
-- where I would expect something like:
-- ((<*>).(<*>)) :: f (g (a -> b)) -> f (g a) -> f (g b)
Is it possible to compose Just (+5) and [1,2,3] in this fashion?
EDIT:
The first step would be to go with either:
pure $ Just (+5) and fmap pure [1,2,3], or
fmap pure (Just (+5) and pure [1,2,3]
But I still don't how to compose these...
EDIT:
It would be nice to have a general way to compose a function f (g (a -> b) and f (g a), I'm not just looking for a solution for the above case, which is just supposed to serve as an example input of such a function. Basically I want a function:
(<***>) :: f (g (a -> b)) -> f (g a) -> f (g b)
liftA2 has a similar compositional property as fmap.
liftA2 f :: f a -> f b -> f c
(liftA2 . liftA2) f :: g (f a) -> g (f b) -> g (f c)
So you can write
(liftA2 . liftA2) ($) (pure (Just (+5))) (fmap pure [1,2,3]) :: [Maybe Integer]
i.e., (<***>) = (liftA2 . liftA2) ($). (much like (<*>) = liftA2 ($))
Another way to look at it is that the composition of applicative functors is an applicative functors, this is made concrete by Data.Functor.Compose:
{-# LANGUAGE ScopedTypeVariables, PartialTypeSignatures #-}
import Data.Functor.Compose
import Data.Coerce
(<***>) :: forall f g a b. (Applicative f, Applicative g)
=> f (g (a -> b)) -> f (g a) -> f (g b)
(<***>) = coerce ((<*>) :: Compose f g (a -> b) -> _)
The point with coerce is to show that (<***>) is the applicative (<*>) for the right type; we can also do the unwrapping manually
f <***> x = getCompose $ Compose f <*> Compose x
We have a f (g (a->b)). To get g a -> g b from g (a->b) we just need <*>, but g (a->b) is wrapped in f. Luckily f is a Functor so we can fmap over it.
Prelude> :t fmap (<*>)
fmap (<*>)
:: (Functor f1, Applicative f) =>
f1 (f (a -> b)) -> f1 (f a -> f b)
Prelude>
That's better, we have a function wrapped in a Functor now. If this Functor happens to be an Applicative, we can apply <*> through it.
Prelude> :t (<*>) . fmap (<*>)
(<*>) . fmap (<*>)
:: (Applicative f, Applicative f1) =>
f1 (f (a -> b)) -> f1 (f a) -> f1 (f b)
Prelude>
Just what the doctor ordered.
Prelude> let (<***>) = (<*>) . fmap (<*>)
Prelude> [Just (+2), Just (*3), Nothing] <***> [Just 7, Just 42, Nothing]
[Just 9,Just 44,Nothing,Just 21,Just 126,Nothing,Nothing,Nothing,Nothing]
Prelude>
Is there a function in the Haskell standard library which takes two functions and returns a function which will return the results of both these functions in a tuple, something like this:
(><) :: (a -> b) -> (a -> c) -> a -> (b, c)
f >< g = \a -> (f a, g a)
So that:
((+2) >< (+3)) 10 == (12,13)
((:[1,2,3]) >< (*2)) 5 == ([5,1,2,3],10)
&&& from Control.Arrow, has signature:
(&&&) :: Control.Arrow.Arrow a => a b c -> a b c' -> a b (c, c')
which is more generic than what you describe, but as shown here, when applied to functions, it resolves to:
(b -> c) -> (b -> c') -> (b -> (c, c'))
and it does what you describe:
\> import Control.Arrow ((&&&))
\> (+2) &&& (+3) $ 10
(12,13)
\> (:[1,2,3]) &&& (*2) $ 5
([5,1,2,3],10)
Use the Applicative instance for functions:
ghci> :t liftA2 (,)
liftA2 (,) :: Applicative f => f a -> f b -> f (a, b)
To make the signature more concrete, we specialize f to a function using TypeApplications (GHC >= 8):
ghci> :set -XTypeApplications
ghci> :t liftA2 #((->) _) (,)
liftA2 #((->)_) (,) :: (t -> a) -> (t -> b) -> t -> (a, b)
Given value f with type :: Applicative f => f (a -> b -> c), What's the best way to map arguments to the inner function.
So far I've found the following:
(\x -> x a b) <$> f
(flip ($ a) b) <$> f
($ b) <$> ($ a) <$> f
I guess my question is why Haskell doesn't have a :: a -> b -> (a -> b -> c) -> c function. Or does it?
The Applicative class has the <*> operator (usually pronounced "ap", and is equivalent to Control.Monad.ap for most Monads), which combined with the <$> operator (itself just an infix alias for fmap) lets you write code like
-- f :: a -> b -> c
-- fa :: Applicative f => f a
-- fb :: Applicative f => f b
f <$> fa <*> fb :: Applicative f => f c
If you need to apply pure arguments, then use the pure method of the Applicative class:
-- f :: a -> b -> c
-- a :: a
-- b :: b
f <$> pure a <*> pure b :: Applicative f => f c
An example might be
sumOfSquares :: Num a => a -> a -> a
sumOfSquares a b = a * a + b * b
> sumOfSquares <$> Just 1 <*> Just 2
Just 5
> sumOfSquares <$> Just 1 <*> Nothing
Nothing
> sumOfSquares <$> pure 1 <*> pure 2 :: Maybe Int
5
> sumOfSquares <$> readLn <*> readLn :: IO Int
1<ENTER>
2<ENTER>
5
The Applicative f => f (a -> b -> c) is being constructed by f <$> here, so if you already had something like
> let g :: IO (Int -> Int -> Int); g = undefined
Then you could just use it as
> g <*> pure 1 <*> pure 2
The <*> operator has the type
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
so if your function has type x -> y -> z, then a ~ x and b ~ y -> z, so repeated application of <*> (get it?) passes more arguments to your wrapped function.
We've got
(<$>) :: Functor f => (a -> b) -> f a -> f b
But you want the opposite
(>$<) :: Functor f => f (a -> b) -> a -> f b
Which we can easily define:
(>$<) f a = ($a) <$> f
So given
f :: Functor f => f (a -> b -> c)
a :: a
b :: b
Then
f >$< a :: f (b -> c)
f >$< a >$< b :: f c
This isn't as idiomatic as <*>, but it works for all Functors, not just Applicatives, which is nice.