在此之前问过这个问题,但没有一个真正的答案。事实上,公认的答案表明这是不可能的,尽管事实是
(<*>) = ap。我读过的关于MaybeT的实现之一
liftA2 (<*>) :: (Applicative f, Applicative f1) => f (f1 (a -> b)) -> f (f1 a) -> f (f1 b)实现应用程序但我不能在这里实现它。我正在进行的工作围绕以下几个方面尝试了许多选择:
-- (<*>) :: StateT s f (a -> b) -> State s f a -> State s f b
instance (Applicative f) => Applicative (StateT s f) where
pure a = StateT $ \s -> pure (a, s)
(StateT f) <*> (StateT g) = StateT $ \s -> -- f :: s -> m (a -> b, s), g :: s -> m (a, s)
let
mabs = f s -- mabs :: m (a -> b, s)
mab = fmap fst mabs
ms' = fmap snd mabs
in undefined我想知道我错过了什么,并希望在这个过程中我能学到一些关于应用程序的东西。
发布于 2015-01-12 14:04:27
一个实现(取自托尼·莫里斯函数式编程课程)可以是
(<*>) :: (Functor f, Monad f) =>
StateT s f (a -> b)
-> StateT s f a
-> StateT s f b
StateT f <*> StateT a =
StateT (\s -> (\(g, t) -> (\(z, u) -> (g z, u)) <$> a t) =<< f s)发布于 2015-01-12 14:37:12
Tony使用了一些替代符号,Simon的回答非常简洁,下面是我最后得出的结论:
-- (<*>) :: StateT s f (a -> b) -> State s f a -> State s f b
instance (Monad f, Applicative f) => Applicative (StateT s f) where
pure a = StateT $ \s -> pure (a, s)
StateT f <*> StateT a =
StateT $ \s ->
f s >>= \(g, t) -> -- (f s) :: m (a->b, s)
let mapper = \(z, u) -> (g z, u) -- :: (a, s) -> (b, s)
in fmap mapper (a t) -- (a t) :: m (a, s)我不得不声明f也是Monad,但这没问题,因为它是Monad转换器定义的一部分,据我所知。
https://stackoverflow.com/questions/27903650
复制相似问题