Search code examples
haskellfrpreactive-banana

Is it possible?: Behavior t [Behavior t a] -> Behavior t [a]


Is there a way to have a Behavior t [a] where the values of [a] at time t are the values contained in a Behavior t [Behavior t a] at time t? I.e, a function with the type of:

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

If this is not possible, is that because of a logical impossibility or a limitation in reactive-banana?


Solution

  • The type is trivially inhabited for any 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 []
    

    which is clearly not what you intended. So let's ask for inhabitation of

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

    or more generally for which applicatives we can construct

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

    This is inhabited for any f that is also a monad:

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

    An obvious question arises: If an applicative has such an f, does it have to be a monad? The answer is yes. We just apply f to the Identity traversable (one-element collection - the Traversable instance of Identity) and construct join as

    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
    

    So our function is inhabited precisely for those applicatives that are also monads.

    To conclude: The function you're seeking would exist if and only if Behavior were a Monad. And because it is not, most likely there is no such function. (I believe that if there were a way how to make it a monad, it'd be included in the library.)