I want to create a function A -> Bool using some lenses of A. For instance:
data A = A { _foo :: Int, _bar :: Int }
makeLenses ''A
l :: [A]
l' = filter (\a -> a^.foo > 100) l
The filter predicate looks a bit clumpsy. ((>100).(^.foo)) is not much better. Without lenses, I would use ((>100) . foo).
Is there a nice way to create such predicates with lens? Ideally it would also allow predicates like (\a -> a^.foo > 100 && a^.bar < 50).
I think ((>100).(^.foo)) is probably the best you can do with just using the standard operators. If you are willing to define new comparison operators for lenses, you could do something like:
import Control.Lens hiding ((.>))
import Control.Monad (liftM2)
import Control.Monad.Reader (MonadReader)
import Data.Function (on)
(.==) :: (MonadReader s m, Eq a) => Getting Bool s a -> a -> m Bool
(.==) l = views l . (==)
infix 4 .==
(.==.) :: (MonadReader s m, Eq a) => Getting a s a -> Getting a s a -> m Bool
(.==.) = liftM2 (==) `on` view
infix 4 .==.
(.<) :: (MonadReader s m, Ord a) => Getting Bool s a -> a -> m Bool
(.<) l = views l . flip (<)
infix 4 .<
(.<.) :: (MonadReader s m, Ord a) => Getting a s a -> Getting a s a -> m Bool
(.<.) = liftM2 (<) `on` view
infix 4 .<.
(.<=) :: (MonadReader s m, Ord a) => Getting Bool s a -> a -> m Bool
(.<=) l = views l . flip (<=)
infix 4 .<=
(.<=.) :: (MonadReader s m, Ord a) => Getting a s a -> Getting a s a -> m Bool
(.<=.) = liftM2 (<=) `on` view
infix 4 .<=.
(.>) :: (MonadReader s m, Ord a) => Getting Bool s a -> a -> m Bool
(.>) l = views l . flip (>)
infix 4 .>
(.>.) :: (MonadReader s m, Ord a) => Getting a s a -> Getting a s a -> m Bool
(.>.) = liftM2 (>) `on` view
infix 4 .>.
(.>=) :: (MonadReader s m, Ord a) => Getting Bool s a -> a -> m Bool
(.>=) l = views l . flip (>=)
infix 4 .>=
(.>=.) :: (MonadReader s m, Ord a) => Getting a s a -> Getting a s a -> m Bool
(.>=.) = liftM2 (>=) `on` view
infix 4 .>=.
(.&&.) :: Monad m => m Bool -> m Bool -> m Bool
(.&&.) = liftM2 (&&)
infix 3 .&&.
(.||.) :: Monad m => m Bool -> m Bool -> m Bool
(.||.) = liftM2 (||)
infix 3 .||.
The logic behind the operator choices is that the dot signifies the side that has a lens, so you could write either foo .== 5 or foo .==. bar (where foo and bar are lenses). Unfortunately, the lens package also defines its own (.<) operator, so maybe some other naming convention would be better. This was just the first idea that came to my mind.
Using these new operators, you would be able to write stuff like
l' = filter (foo .> 100 .&&. bar .< 50) l
Related
I am trying to understand why adding id in the last line of the sequence below removes the monadic aspect:
Prelude> :t id
id :: a -> a
Prelude> :t Control.Monad.liftM2
Control.Monad.liftM2
:: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r
Prelude> :t (==)
(==) :: Eq a => a -> a -> Bool
Prelude> :t Control.Monad.liftM2 (==)
Control.Monad.liftM2 (==)
:: (Monad m, Eq a) => m a -> m a -> m Bool
Prelude> :t Control.Monad.liftM2 (==) id
Control.Monad.liftM2 (==) id :: Eq a => (a -> a) -> a -> Bool
Prelude>
How does adding id :: a -> a change the signature in the way it does in the last line ?
You’re fixing the type to a particular Monad instance, namely the “function reader” monad (instance Monad ((->) a)).
id :: a -> a and you are attempting to use it as an argument to a parameter of type m a, so:
m a ~ a -> a
m a ~ (->) a a
m a ~ ((->) a) a
m ~ (->) a
a ~ a
The remainder of the signature is:
m a -> m Bool
And since m ~ (->) a, the resulting type is:
(->) a a -> (->) a Bool
(a -> a) -> (a -> Bool)
(a -> a) -> a -> Bool
(Plus the Eq a constraint from the use of ==.)
This is useful in pointfree code, particularly using the Applicative instance, since you can implicitly “spread” the argument of a function to subcomputations:
nextThree = (,,) <$> (+ 1) <*> (+ 2) <*> (+ 3)
-- or
nextThree = liftA3 (,,) (+ 1) (+ 2) (+ 3)
nextThree 5 == (6, 7, 8)
uncurry' f = f <$> fst <*> snd
-- or
uncurry' f = liftA2 f fst snd
uncurry' (+) (1, 2) == 3
The signature of liftM2 (==) is (Monad m, Eq a) => m a -> m a -> m Bool. So that means that if we call this function with id :: b -> b as argument, then it means that m a and b -> b are the same type.
The fact that m ~ (->) b holds is not a problem since (->) r is an instance of Monad, indeed in the GHC.Base source code we see:
-- | #since 2.01
instance Monad ((->) r) where
f >>= k = \ r -> k (f r) r
This only makes sense if m ~ (->) b. Here the arrow (->) is a type constructor, and (->) a b is the same as a -> b.
So it means that if we calculate the type of liftM2 (==) id, we derive the following:
liftM2 (==) :: m a -> m a -> m Bool
id :: (b -> b)
-------------------------------------------
m ~ (->) b, a ~ b
This thus means that the output type of liftM2 (==) id is liftM2 (==) id :: (Monad m, Eq a) => m a -> m Bool, but we need to "specialize" this with the knowledge we obtained: that m a is (->) b and a is the same type as b, so:
liftM2 (==) id :: (Monad m, Eq a) => m a -> m Bool
-> liftM2 (==) id :: (Monad m, Eq a) => (b -> a) -> (b -> Bool)
-> liftM2 (==) id :: Eq b => (b -> b) -> (b -> Bool)
-> liftM2 (==) id :: Eq b => (b -> b) -> b -> Bool
In short the function is still "monadic", although by using id, you have selected a specific monad, and thus the function is no longer applicable to all sorts of monads, only to the (->) r monad.
I'm trying to do one of the Monoid exercises in Haskell Book (Chapter 15, "Monoid, Semigroup") but I'm stuck. The following is given:
newtype Combine a b =
Combine { unCombine :: (a -> b) }
and I'm supposed to write the Monoid instance for Combine.
I wrote something like this:
instance (Semigroup b) => Semigroup (Combine a b) where
Combine { unCombine = f } <> Combine { unCombine = g } =
Combine { unCombine = \x -> f x <> g x }
instance (Monoid b) => Monoid (Combine a b) where
mempty = Combine { unCombine = \_ -> mempty }
mappend = (<>)
but I do not know how to write the quickCheck for the instance.
Here is my try (does not compile):
monoidLeftIdentity1 :: (Eq m, Monoid m) => m -> Bool
monoidLeftIdentity1 x = mappend mempty x == x
monoidRightIdentity1 :: (Eq m, Monoid m) => m -> Bool
monoidRightIdentity1 x = mappend x mempty == x
main :: IO ()
main = do
quickCheck (monoidLeftIdentity1 :: Combine Int (Sum Int) -> Bool)
quickCheck (monoidRightIdentity1 :: Combine Int (Sum Int) -> Bool)
It seems I must instance Arbitrary and Eq on this type, but how to write them for a function?
There is a similar question, in that question, we are asked to write the Semigroup instance for Combine.
First a full code example:
module Main where
import Test.QuickCheck
import Data.Monoid
newtype Combine a b = Combine { unCombine :: a -> b }
instance (Semigroup b) => Semigroup (Combine a b) where
a <> _ = a
-- (Combine f) <> (Combine g) = Combine $ \a -> (f a) <> (g a)
instance (Monoid b) => Monoid (Combine a b) where
mempty = Combine $ \_ -> mempty
monoidLeftIdentity :: (Eq m, Monoid m) => m -> Bool
monoidLeftIdentity m = mappend mempty m == m
monoidRightIdentity :: (Eq m, Monoid m) => m -> Bool
monoidRightIdentity m = mappend m mempty == m
monoidLeftIdentityF :: (Eq b, Monoid m) => (Fun a b -> m) -> (m -> a -> b) -> a -> Fun a b -> Bool
monoidLeftIdentityF wrap eval point candidate = eval (mappend mempty m) point == eval m point
where m = wrap candidate
monoidRightIdentityF :: (Eq b, Monoid m) => (Fun a b -> m) -> (m -> a -> b) -> a -> Fun a b -> Bool
monoidRightIdentityF wrap eval point candidate = eval (mappend m mempty) point == eval m point
where m = wrap candidate
main :: IO ()
main = do
quickCheck $ (monoidLeftIdentityF (Combine . applyFun) unCombine :: Int -> Fun Int (Sum Int) -> Bool)
quickCheck $ (monoidRightIdentityF (Combine . applyFun) unCombine :: Int -> Fun Int (Sum Int) -> Bool)
What are we doing here?
First we need a way to generate random functions. That is, what this Fun thing is about. There is an Arbitrary instance for Fun a b, if there are certain instances available for a and b. But most of the time we have those.
A value of type Fun a b can be shown, so Fun a b has a show instance, provided a and b have one. We can extract the function with applyFun.
For QuickCheck to take advantage of this, we need to provide a Testable where all argument positions can be randomly generated and shown.
So we have to formulate our Properties in terms of a, b and Fun a b.
To connect all of this with Combine we provide a function from Fun a b to Combine a b.
Now we are stuck with another problem. We can't compare functions, so we can't compare values of type Combine a b for equality. As we are already randomly generating test cases, why not just generate the points, on which to test the functions for equality, also randomly. The equality will not be a sure thing, but we are hunting the falsifiable examples! So that is good enough for us. To do that, we provide a function to "apply" a value of type Combine a b to a value of type a, to get a value of type b, which can hopefully be compared for equality.
You can use Test.QuickCheck.Function to generate random function values, so you should be able to write something like the following to take care of the Arbitrary constraint:
quickCheck (monoidLeftIdentity1 . Combine . apply :: Fun Int (Sum Int) -> Bool)
For the Eq constraint, however, you will have trouble comparing function values. I think it should be enough to just check pointwise equality for some sampling of inputs, e.g.
funoidLeftIdentity1 :: (Monoid b, Eq b) => Fun a b -> a -> Bool
funoidLeftIdentity1 (Fn f) x = uncombine (Combine f <> mempty) x == uncombine mempty x
tl;dr: is it possible to use any of the lens family of abstractions to wrap/unwrap any arbitrary newtype (that provides an instance for such abstractions)?
I'll motivate my question by a simple example, based on a true story. Suppose I define the following newtype:
newtype FreeMonoid a = FreeMonoid { asMap :: Map a Int }
which is used to represent terms of the form:
a0 <> a1 <> ... <> an-1
We can represent free-monoids as lists:
instance Ord a => IsList (FreeMonoid a) where
type Item (FreeMonoid a) = a
fromList xs = FreeMonoid $ Map.fromListWith (+) $ zip xs (repeat 1)
toList (FreeMonoid p) = do
(x, n) <- Map.toList p
genericReplicate n x
Two examples of free-monoids are sequences of sum and sequences of products:
type FreeSum a = FreeMonoid (Sum a)
type FreeProduct a = FreeMonoid (Product a)
Where Sum and Product are defined in Data.Monoid. Now we could define fromList and toList operations for FreeSum and
FreeProduct as follows:
fromListSum :: Ord a => [a] -> FreeSum a
fromListSum = fromList . (Sum <$>)
fromListProduct :: Ord a => [a] -> FreeProduct a
fromListProduct = fromList . (Product <$>)
But this has quite a lot of boilerplate. It'd be nicer if we could simply say:
fromListW :: (Ord a, Wrapper f) => [a] -> FreeMonoid (f a)
fromListW = fromList . (wrap <$>)
where wrap is some operation of the (hypotetical) Wrapper class were:
wrap :: a -> f a
unwrap :: f a -> a
Similarly, I'd like to be able to write a function:
toListW :: (Ord a, Wrapper f) => FreeMonoid (f a) -> [a]
toListW = (unwrap <$>) . toList
Lenses seem to provide such an abstraction in Control.Lens.Wrapped (for which Sum and Product in this example are instances of the typeclasses there!). However my attempts to understand and use the abstractions in this module have failed. For instance:
fromListW :: (Ord a, Wrapped (f a)) => [a] -> FreeMonoid (f a)
fromListW = fromList . (Wrapped <$>)
won't work since the argument is not a list of Unwrapped (f a).
So my question is:
Do lenses provide an abstraction similar to this Wrapper class?
If not, can this "scrap-your-boilerplate" problem be solved by using lenses?
The "problem" is that you're using Wrapped, which is really meant to be a convenience pattern synonym and not a wrapping "constructor". Because it's designed to support polymorphic wrapping, you need to assert that your type can be rewrapped:
fromListW :: (Rewrapped a a, Ord a) => [Unwrapped a] -> FreeMonoid a
fromListW = fromList . (Wrapped <$>)
This then works as expected:
> let x = [1,2,3]
> fromListW x :: FreeMonoid (Sum Int)
FreeMonoid {asMap = fromList [(Sum {getSum = 1},...
> fromListW x :: FreeMonoid (Product Int)
FreeMonoid {asMap = fromList [(Product {getProduct = 1},...
>
I think a more idiomatic lens implementation would be:
fromListW :: (Rewrapped a a, Ord a) => [Unwrapped a] -> FreeMonoid a
fromListW = fromList . view (mapping _Unwrapped)
This still requires the Rewrapped a a constraint, but you can use the non-polymorphic _Unwrapped' instead:
fromListW :: (Wrapped a, Ord a) => [Unwrapped a] -> FreeMonoid a
fromListW = fromList . view (mapping _Unwrapped')
which looks a little more natural.
The toListW implementation would have similar structure:
toListW :: (Wrapped a, Ord a) => FreeMonoid a -> [Unwrapped a]
toListW = view (mapping _Wrapped') . toList
For example, typing :t ap in GHCi gives the result
ap :: Monad m => m (a -> b) -> m a -> m b
If I already know the Monad instance I'm going to use is ((->) r), how can I query for the type of ap for that specific instance?
As Lazersmoke said as a comment you can use the TypeApplications extension that was introduced in GHC 8.0.
In GHCi:
λ > :set -XTypeApplications
λ > import Control.Monad
λ > :t ap #((->) _)
ap #((->) _) :: (t -> a -> b) -> (t -> a) -> t -> b
You can use visible type application feature to specify parametric types. You can look at functions in more creative way: functions in Haskell can be applied to not only values of some types, but also to types of that values. But to pass type you should somehow specify (with prepending #) that you're passing types (because types are not first-class objects in Haskell yet).
So here how it works:
λ: :set -XTypeApplications
λ: :t ap #((->) Int)
ap #((->) Int) :: (Int -> a -> b) -> (Int -> a) -> Int -> b
The only limitation of such approach is that you can't use type variables in ghci, you should use specific types (Int instead of r) but this is not big deal.
ADVANCED SECTION
Well, actually you can, but it's tricky:
λ: :set -XExplicitForAll
λ: :set -XPartialTypeSignatures
λ: :set -XScopedTypeVariables
λ: :{
λ| foo :: forall r . _
λ| foo = ap #((->) r)
λ| :}
<interactive>:28:19: warning: [-Wpartial-type-signatures]
• Found type wildcard ‘_’
standing for ‘(r -> a -> b) -> (r -> a) -> r -> b’
λ: :t foo
foo :: (r -> a -> b) -> (r -> a) -> r -> b
UPD: You can actually use placeholders instead of type variables (see another answer). But if you want to specify exact names use approach from above.
λ: :t ap #((->) _)
ap #((->) _) :: (t -> a -> b) -> (t -> a) -> t -> b
/ADVANCED SECTION
One more thing to say about this approach: you should do something more if your functions have several type parameters and you want to specify exact one. Types are passed one by one from left to right just as simple arguments in some function like bar :: Int -> String -> Double. If you want to fix first argument of bar you should write bar 5 and if you want to fix second, then, well, you can write something like \n -> bar n "baz" but this doesn't work with type application. You need to know two things:
Order of types.
How to specify desired type.
Consider next function:
λ: :t lift
lift :: (Monad m, MonadTrans t) => m a -> t m a
We want be able to specify m and t type variables. Because Haskell has no named type variables (yet) you can't write :t lift {t=MaybeT} or :t lift {m=IO} unfortunately. So go back to two things.
To see order of types you should use some compiler options. Order of type arguments is specified by forall and you can do it manually. Otherwise type parameters will be sorted somehow by the compiler. Mere mortals can't see order of types for lift function but if you're aware of some high-level magic you can:
λ: :set -fprint-explicit-foralls
λ: :t lift
lift
:: forall {t :: (* -> *) -> * -> *} {a} {m :: * -> *}.
(Monad m, MonadTrans t) =>
m a -> t m a
And then you should use #_ to skip some types:
λ: :t lift #MaybeT
lift #MaybeT
:: forall {a} {m :: * -> *}. Monad m => m a -> MaybeT m a
λ: :t lift #_ #IO
lift #_ #IO
:: forall {t :: (* -> *) -> * -> *} {a}.
MonadTrans t =>
IO a -> t IO a
λ: :t lift #_ #_ #Int
lift #_ #_ #Int
:: forall {t :: (* -> *) -> * -> *} {t1 :: * -> *}.
(Monad t1, MonadTrans t) =>
t1 Int -> t t1 Int
Well, this is really mystery for me why m is shown as third argument in forall but should be passed as second but I'm still not aware of all magic.
This is just a hack, but you could always do something like:
:t ap . (id :: ((->) r a) -> ((->) r a))
or
:t \x y -> (id :: ...) (ap x y)
interestingly
Prelude Control.Monad> type Reader = (->) r
Prelude Control.Monad> :t ap . (id :: Reader r a -> Reader r a)
ap . (id :: Reader r a -> Reader r a)
:: Reader r (a -> b) -> (r -> a) -> r -> b
differs from
Prelude Control.Monad> :t \x y -> (id :: Reader r a -> Reader r a) (ap x y)
\x y -> (id :: Reader r a -> Reader r a) (ap x y)
:: (r -> a1 -> a) -> (r -> a1) -> Reader r a
in what ghc recognizes as the synonym Reader r a
There I was, writing a function that takes a value as input, calls a function on that input, and if the result of that is Just x, it should return x; otherwise, it should return the original input.
In other words, this function (that I didn't know what to call):
foo :: (a -> Maybe a) -> a -> a
foo f x = fromMaybe x (f x)
Since it seems like a general-purpose function, I wondered if it wasn't already defined, so I asked on Twitter, and Chris Allen replied that it's ap fromMaybe.
That sounded promising, so I fired up GHCI and started experimenting:
Prelude Control.Monad Data.Maybe> :type ap
ap :: Monad m => m (a -> b) -> m a -> m b
Prelude Control.Monad Data.Maybe> :type fromMaybe
fromMaybe :: a -> Maybe a -> a
Prelude Control.Monad Data.Maybe> :type ap fromMaybe
ap fromMaybe :: (b -> Maybe b) -> b -> b
The type of ap fromMaybe certainly looks correct, and a couple of experiments seem to indicate that it has the desired behaviour as well.
But how does it work?
The fromMaybe function seems clear to me, and in isolation, I think I understand what ap does - at least in the context of Maybe. When m is Maybe, it has the type Maybe (a -> b) -> Maybe a -> Maybe b.
What I don't understand is how ap fromMaybe even compiles. To me, this expression looks like partial application, but I may be getting that wrong. If this is the case, however, I don't understand how the types match up.
The first argument to ap is m (a -> b), but fromMaybe has the type a -> Maybe a -> a. How does that match? Which Monad instance does the compiler infer that m is? How does fromMaybe, which takes two (curried) arguments, turn into a function that takes a single argument?
Can someone help me connect the dots?
But that use of ap is not in the context of Maybe. We're using it with a function, fromMaybe, so it's in the context of functions, where
ap f g x = f x (g x)
Among the various Monad instances we have
instance Monad ((->) r)
so it is
ap :: Monad m => m (a -> b) -> m a -> m b
fromMaybe :: r -> (Maybe r -> r)
ap :: (r -> (a -> b)) -> (r -> a) -> (r -> b)
ap f g x :: b
ap fromMaybe :: (r -> a) -> (r -> b) , a ~ Maybe r , b ~ r
because -> in types associates to the right: a -> b -> c ~ a -> (b -> c). Trying to plug the types together, we can only end up with that definition above.
And with (<*>) :: Applicative f => f (a -> b) -> f a -> f b, we can write it as (fromMaybe <*>), if you like this kind of graffiti:
#> :t (fromMaybe <*>)
(fromMaybe <*>) :: (r -> Maybe r) -> r -> r
As is rightfully noted in another answer here, when used with functions, <*> is just your good ole' S combinator. We can't very well have function named S in Haskell, so <*> is just a part of standard repertoire of the point-free style of coding. Monadic bind (more so, flipped), =<<, can be even more mysterious, but a pointfree coder just doesn't care and will happily use it to encode another, similar pattern,
(f =<< g) x = f (g x) x
in combinatory function calls, mystery or no mystery (zipWith (-) =<< drop 1 comes to mind).
Apologies for laconic and mechanical answer. I don't like cherry-picking things like Applicative or Monad, but I don't know where you're at. This is not my usual approach to teaching Haskell.
First, ap is really (<*>) under the hood.
Prelude> import Control.Monad
Prelude> import Data.Maybe
Prelude> import Control.Applicative
Prelude> :t ap
ap :: Monad m => m (a -> b) -> m a -> m b
Prelude> :t (<*>)
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
What does this mean? It means we don't need something as "strong" as Monad to describe what we're doing. Applicative suffices. Functor doesn't, though.
Prelude> :info Applicative
class Functor f => Applicative (f :: * -> *) where
pure :: a -> f a
(<*>) :: f (a -> b) -> f a -> f b
Prelude> :info Functor
class Functor (f :: * -> *) where
fmap :: (a -> b) -> f a -> f b
Here's ap/(<*>) with the Maybe Monad/Applicative:
Prelude> ap (Just (+1)) (Just 1)
Just 2
Prelude> (<*>) (Just (+1)) (Just 1)
Just 2
First thing to figure out is, which instance of the typeclass Applicative are we talking about?
Prelude> :t fromMaybe
fromMaybe :: a -> Maybe a -> a
Desugaring fromMaybe's type a bit gives us:
(->) a (Maybe a -> a)
So the type constructor we're concerned with here is (->). What does GHCi tell us about (->) also known as function types?
Prelude> :info (->)
data (->) a b -- Defined in ‘GHC.Prim’
instance Monad ((->) r) -- Defined in ‘GHC.Base’
instance Functor ((->) r) -- Defined in ‘GHC.Base’
instance Applicative ((->) a) -- Defined in ‘GHC.Base’
Hrm. What about Maybe?
Prelude> :info Maybe
data Maybe a = Nothing | Just a -- Defined in ‘GHC.Base’
instance Monad Maybe -- Defined in ‘GHC.Base’
instance Functor Maybe -- Defined in ‘GHC.Base’
instance Applicative Maybe -- Defined in ‘GHC.Base’
What happened with the use of (<*>) for Maybe was this:
Prelude> (+1) 1
2
Prelude> (+1) `fmap` Just 1
Just 2
Prelude> Just (+1) <*> Just 1
Just 2
Prelude> :t fmap
fmap :: Functor f => (a -> b) -> f a -> f b
Prelude> let mFmap = fmap :: (a -> b) -> Maybe a -> Maybe b
Prelude> (+1) `mFmap` Just 1
Just 2
Prelude> :t (<*>)
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
Prelude> let mAp = (<*>) :: Maybe (a -> b) -> Maybe a -> Maybe b
Prelude> :t (+1)
(+1) :: Num a => a -> a
Prelude> :t Just (+1)
Just (+1) :: Num a => Maybe (a -> a)
Prelude> Just (+1) `mAp` Just 1
Just 2
Okay, what about the function type's Functor and Applicative? One of the tricky parts here is that (->) has be to be partially applied in the type to be a Functor/Applicative/Monad. So your f becomes (->) a of the overall (->) a b where a is an argument type and b is the result.
Prelude> (fmap (+1) (+2)) 0
3
Prelude> (fmap (+1) (+2)) 0
3
Prelude> :t fmap
fmap :: Functor f => (a -> b) -> f a -> f b
Prelude> let funcMap = fmap :: (a -> b) -> (c -> a) -> c -> b
Prelude> -- f ~ (->) c
Prelude> (funcMap (+1) (+2)) 0
3
Prelude> :t (<*>)
(<*>) :: Applicative f => f (a -> b) -> f a -> f b
Prelude> let funcAp = (<*>) :: (c -> a -> b) -> (c -> a) -> (c -> b)
Prelude> :t fromMaybe
fromMaybe :: a -> Maybe a -> a
Prelude> :t funcAp fromMaybe
funcAp fromMaybe :: (b -> Maybe b) -> b -> b
Prelude> :t const
const :: a -> b -> a
Prelude> :t funcAp const
funcAp const :: (b -> b1) -> b -> b
Not guaranteed to be useful. You can tell funcAp const isn't interesting just from the type and knowing how parametricity works.
Edit: speaking of compose, the Functor for (->) a is just (.). Applicative is that, but with an extra argument. Monad is the Applicative, but with arguments flipped.
Further whuttery: Applicative <*> for (->) a) is S and pure is K of the SKI combinator calculus. (You can derive I from K and S. Actually you can derive any program from K and S.)
Prelude> :t pure
pure :: Applicative f => a -> f a
Prelude> :t const
const :: a -> b -> a
Prelude> :t const
const :: a -> b -> a
Prelude> let k = pure :: a -> b -> a
Prelude> k 1 2
1
Prelude> const 1 2
1
I'm going to relabel the type arguments, for clarity.
ap :: Monad m => m (a -> b) -> m a -> m b
fromMaybe :: c -> Maybe c -> c
Which Monad instance does the compiler infer that m is?
((->) r) is a Monad. This is all functions that have type r as their argument, for some specific r.
So in the type:
ap :: Monad m => m (a -> b) -> m a -> m b
m ~ (c ->), a ~ Maybe c and b ~ c.
The return type, m a -> m b, expands to (c -> Maybe c) -> c -> c - which is the type of ap fromMaybe.
The monad you are looking for is (->) r or r -> _ if you prefer infix syntax.
Then the signature of ap expands to:
m (a -> b) -> m a -> m b =
(r -> (a -> b)) -> (r -> a) -> r -> b = -- now we use the signature of fromMaybe
(b -> (Maybe b -> b)) -> (b -> Maybe b) -> b -> b
Now if you consider ap fromMaybe as a partially applied function and voila you get the desired result.