有可能吗?:行为t [行为t a] - >行为t [a]

时间:2014-01-02 04:31:05

标签: haskell frp reactive-banana

有没有办法让Behavior t [a]时间t的[a]值是时间t Behavior t [Behavior t a]中包含的值?即,类型为的函数:

Behavior t [Behavior t a] -> Behavior t [a]

如果这是不可能的,那是因为逻辑不可能还是反应性香蕉的限制?

2 个答案:

答案 0 :(得分:12)

对于任何Applicative

,该类型都非常有人居住
{-# LANGUAGE RankNTypes #-}
import Control.Applicative
import Control.Monad
import Data.Functor.Identity
import qualified Data.Traversable as T

f' :: (Applicative f) => f [f a] -> f [a]
f' = const $ pure []

这显然不是你想要的。所以我们要求居住

(Traversable t) => Behavior u (t (Behavior u a)) -> Behavior u (t a)

或更一般地,我们可以构建的应用程序

(T.Traversable t) => f (t (f a)) -> f (t a)

这适用于任何也是monad的f

f :: (Monad m, T.Traversable t) => m (t (m a)) -> m (t a)
f = join . liftM T.sequence

一个显而易见的问题出现了:如果一个申请者有这样的f,它是否必须是一个单子?答案是。我们只需将f应用于Identity遍历(单元素集合 - Traversable Identity实例)并构建join

g :: (Applicative m) => (forall t . (T.Traversable t) => m (t (m a)) -> m (t a))
                     -> (m (m a) -> m a)
g f = fmap runIdentity . f . fmap Identity

因此,我们的功能正好适用于那些也是monad的应用程序。

总结:当且仅当BehaviorMonad时,您所寻求的功能才会存在。而且因为它不是,所以很可能没有这样的功能功能。 (我相信如果有一种方法可以让它成为一个单子格,它就会被包含在图书馆中。)

答案 1 :(得分:2)

正如彼得已经指出的那样,这样的功能

flatten :: Behavior t [Behavior t a] -> Behavior t [a]
当且仅当类型Behavior t是monad时才存在

这是直接看到这个的方法:

join :: Behavior t (Behavior t a) -> Behavior t a
join = map head . flatten . map (:[])

flatten = join . map sequence

但是,出于各种原因,Behavior t 是反应性香蕉中的monad。这是explained here