haskell - How does ap fromMaybe compose? -


there was, writing function takes value input, calls function on input, , if result of just x, should return x; otherwise, should return original input.

in other words, function (that didn't know call):

foo :: (a -> maybe a) -> -> foo f x = frommaybe x (f x) 

since seems general-purpose function, wondered if wasn't defined, i asked on twitter, , chris allen replied it's ap frommaybe.

that sounded promising, fired ghci , started experimenting:

prelude control.monad data.maybe> :type ap ap :: monad m => m (a -> b) -> m -> m b prelude control.monad data.maybe> :type frommaybe frommaybe :: -> maybe -> prelude control.monad data.maybe> :type ap frommaybe ap frommaybe :: (b -> maybe b) -> b -> b 

the type of ap frommaybe looks correct, , couple of experiments seem indicate has desired behaviour well.

but how work?

the frommaybe function seems clear me, , in isolation, think understand ap - @ least in context of maybe. when m maybe, has type maybe (a -> b) -> maybe -> maybe b.

what don't understand how ap frommaybe compiles. me, expression looks partial application, may getting wrong. if case, however, don't understand how types match up.

the first argument ap m (a -> b), frommaybe has type a -> maybe -> a. how match? monad instance compiler infer m is? how frommaybe, takes 2 (curried) arguments, turn function takes single argument?

can me connect dots?

apologies laconic , mechanical answer. don't cherry-picking things applicative or monad, don't know you're at. not usual approach teaching haskell.

first, ap (<*>) under hood.

prelude> import control.monad prelude> import data.maybe prelude> import control.applicative prelude> :t ap ap :: monad m => m (a -> b) -> m -> m b prelude> :t (<*>) (<*>) :: applicative f => f (a -> b) -> f -> f b 

what mean? means don't need "strong" monad describe we're doing. applicative suffices. functor doesn't, though.

prelude> :info applicative class functor f => applicative (f :: * -> *)   pure :: -> f   (<*>) :: f (a -> b) -> f -> f b prelude> :info functor class functor (f :: * -> *)   fmap :: (a -> b) -> f -> f b 

here's ap/(<*>) maybe monad/applicative:

prelude> ap (just (+1)) (just 1) 2 prelude> (<*>) (just (+1)) (just 1) 2 

first thing figure out is, instance of typeclass applicative talking about?

prelude> :t frommaybe frommaybe :: -> maybe -> 

desugaring frommaybe's type bit gives us:

(->) (maybe -> a) 

so type constructor we're concerned here (->). ghci tell (->) known function types?

prelude> :info (->) data (->) 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. maybe?

prelude> :info maybe data maybe = nothing |     -- 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 use of (<*>) maybe this:

prelude> (+1) 1 2 prelude> (+1) `fmap` 1 2 prelude> (+1) <*> 1 2 prelude> :t fmap fmap :: functor f => (a -> b) -> f -> f b prelude> let mfmap = fmap :: (a -> b) -> maybe -> maybe b prelude> (+1) `mfmap` 1 2 prelude> :t (<*>) (<*>) :: applicative f => f (a -> b) -> f -> f b prelude> let map = (<*>) :: maybe (a -> b) -> maybe -> maybe b prelude> :t (+1) (+1) :: num => -> prelude> :t (+1) (+1) :: num => maybe (a -> a) prelude> (+1) `map` 1 2 

okay, function type's functor , applicative? 1 of tricky parts here (->) has partially applied in type functor/applicative/monad. f becomes (->) a of overall (->) b a argument type , b result.

prelude> (fmap (+1) (+2)) 0 3 prelude> (fmap (+1) (+2)) 0 3 prelude> :t fmap fmap :: functor f => (a -> b) -> f -> 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 -> f b prelude> let funcap = (<*>) :: (c -> -> b) -> (c -> a) -> (c -> b) prelude> :t frommaybe frommaybe :: -> maybe -> prelude> :t funcap frommaybe funcap frommaybe :: (b -> maybe b) -> b -> b prelude> :t const const :: -> b -> prelude> :t funcap const funcap const :: (b -> b1) -> b -> b 

not guaranteed useful. can tell funcap const isn't interesting type , knowing how parametricity works.

edit: speaking of compose, functor (->) a (.). applicative that, argument. monad applicative, arguments flipped.

further whuttery: applicative <*> (->) a) s , pure k of ski combinator calculus. (you can derive k , s. can derive program k , s.)

prelude> :t pure pure :: applicative f => -> f prelude> :t const const :: -> b -> prelude> :t const const :: -> b -> prelude> let k = pure :: -> b -> prelude> k 1 2 1 prelude> const 1 2 1 

Comments

Popular posts from this blog

how to insert data php javascript mysql with multiple array session 2 -

multithreading - Exception in Application constructor -

windows - CertCreateCertificateContext returns CRYPT_E_ASN1_BADTAG / 8009310b -