|
|
|
|
|
by Iceland_jack
1407 days ago
|
|
In the definitional sense it is underwhelming, like with many algebraic structures the diversity of instances leads to interesting results. The behaviour of these instantiations have a completely different character even though they instantiate the same pattern replicateM :: Int -> [a] -> [[a]]
replicateM :: Int -> Cont r a -> Cont r [a]
sequenceA :: [IO a] -> IO [a]
sequenceA :: Maybe (x -> a) -> (x -> Maybe a)
sequenceA :: Map key (Parser a) -> Parser (Map key a)
In fact both of them require only an Applicative pattern (aka n-ary lifting) which is weaker than Monad liftA0 :: Applicative f => (a) -> (f a)
liftA1 :: Functor f => (a -> b) -> (f a -> f b)
liftA2 :: Applicative f => (a -> b -> c) -> (f a -> f b -> f c)
liftA3 :: Applicative f => (a -> b -> c -> d) -> (f a -> f b -> f c -> f d)
liftA4 :: Applicative f => ..
where
liftA0 = pure
liftA1 = fmap
but has more interesting properties than Monad. Because there is no dependency between Applicative computations they can be run Concurrently[1] or Backwards[2]. They are also closed under Compose-ition[3]. This is not even mentioning what makes an Applicative or a Monad. Functor instances are unique[4] but a single type constructor can have different law-abiding Applicative instances.[5][1] https://hackage.haskell.org/package/async/docs/Control-Concu... [2] https://hackage.haskell.org/package/transformers-0.6.0.4/doc... [3] https://hackage.haskell.org/package/base-4.16.3.0/docs/Data-... [4] https://stackoverflow.com/questions/19774904/are-functor-ins... [5] https://hackage.haskell.org/package/idiomatic |
|