ivanperez-keera / dunai

Classic FRP, Arrowized FRP, Reactive Programming, and Stream Programming, all via Monadic Stream Functions
205 stars 30 forks source link

How does creating and destroying objects work #229

Closed walseb closed 4 years ago

walseb commented 4 years ago

Hi! So yampa has ListSFas discussed here. In bearriver/dunai, using the list monad transformer seems to be the way to go, but the example in "Functional Reactive Programming, Refactored" section 4.4 doesn't compile in dunai and I haven't been able to get a it working

The main problem is that liftS doesn't seem to exist in dunai. For example in:

manyObjs :: (Monad m) => MSF (ClockInfo (ListT m)) () (V2 Double)
manyObjs = obj : obj

obj :: SF () (V2 Double)
obj = proc () -> do
  pos <- ((integralFrom (V2 0 0)) <<< (integralFrom (V2 0 0))) -< (V2 0 1)
  returnA -< pos

I get the error:

      Expected type: MSF (ClockInfo (ListT m)) () (V2 Double)
        Actual type: MSF (ClockInfo Identity) () (V2 Double)

Because the move MSF isn't lifted into ListT. How do I do this and is there anything else I need to think about? Also are there any bearriver projects using ListT or other monads like EitherT, Maybe, etc.

Thanks!

turion commented 4 years ago

I don't know about Yampa, but if you use FRP.BearRiver, yourSFs have an extra argumentmwhich is the monad inside theClockInfo. You can use that to set it toListT m`.

walseb commented 4 years ago

Sorry, my problem was with not understanding monad transformers in general. Now that I have a better understanding of it, this is essentially my problem:

-- this works
intList :: (Monad m) => (ListT m) Int
intList = lift int

int :: (Monad m) => m Int
int = pure 7

-- This doesn't
objList :: (Monad m) => MSF (ListT m) () ()
objList = lift obj -- Error here

obj :: (Monad m) => MSF m () ()
obj = undefined

The error I get is:

    • Couldn't match kind ‘*’ with ‘* -> *’
      When matching types
        t0 :: (* -> *) -> * -> *
        MSF (ListT m) :: * -> * -> *
      Expected type: MSF (ListT m) () ()
        Actual type: t0 (MSF m0 ()) ()

Which to me seems like I'm using the wrong lift operator, because the kind signature doesn't seem to match. But I can't find the one used in the paper (liftS) in https://hackage.haskell.org/package/dunai-0.7.0/docs/Control-Monad-Trans-MSF-List.html

turion commented 4 years ago

Yes, it's really a wart that we don't have liftS anymore. @ivanperez-keera Maybe it's possible to bring it back with a deprecation comment?

@walseb In your example, we're looking for something that lifts an MSF along a monad morphism (lift in this case), so something of type signature (forall x . m x -> n x) -> MSF m a b -> MSF n a b. Hoogle finds the required function: https://hoogle.haskell.org/?hoogle=%28forall+a+.+m+a+-%3E+n+a%29+-%3E+MSF+m+a+b+-%3E+MSF+n+a+b&scope=package%3Adunai It's morphS.

walseb commented 4 years ago

Thanks! It works now!

turion commented 4 years ago

Awesome! So is this issue resolved then?

walseb commented 4 years ago

Oh yeah I forgot to close it