3

I'm trying to get this small piece of code to compile.

module Sodium where import Prelude import Control.Monad.Free import Data.Coyoneda import Data.Tuple data ReactiveF more = RFNewEvent (forall a. (Tuple (Event a) (a -> Reactive Unit) -> more)) type Reactive a = FreeC ReactiveF a data Event a = Event a newEvent :: forall a. Reactive (Tuple (Event a) (a -> Reactive Unit)) newEvent = liftFC $ RFNewEvent id 

If I instead use "Number" instead of "a" in RFNewEvent, then everything compiles fine. But the moment I go "forall a." and replace "Number" with "a" it no longer compiles.

I get the following error message

Cannot unify type a1 with type a0 

Does anyone know how to make this work?

I'm using version 0.5.0 of purescript-free.

Edit

If I use the following

data NewEventData = NewEventData forall a. Tuple (Event a) (a -> Reactive Unit) 

and substitute it into RFNewEvent, then it will compile. But I end up with an undesired type signature for newEvent.

newEvent :: Reactive NewEventData newEvent = liftFC $ RFNewEvent id 

Which lets me create an event, but lets me shoot different event values to the event stream instead of the same type of value. (missing forall a. now on newEvent)

I might of made a mistake.

The overall goal is to simulate SodiumFRP's interface using a Free Monad. Then plug in an existing JavaScript FRP library that works similar to Sodium via FFI when interpreting the Free Monad.

Is this possible?

3
  • 1
    I suspect you want an existential quantifier, not a universal quantifier? Have you seen purescript-exists? Commented Oct 24, 2015 at 22:40
  • No I haven't seen purescript-exists. Having a look at it now. Although I may have made a mistake in my design. Commented Oct 24, 2015 at 23:13
  • 1
    @ Phil Freeman. Yes you are write. purescript-exists makes it possible to define "sample". (the next part i was stuck on) Commented Oct 25, 2015 at 1:53

1 Answer 1

2

The following code now compiles and has the desired type signature for "newEvent"

module FRP.Sodium where import Prelude import Control.Monad.Free import Data.Coyoneda import Data.Tuple data ReactiveF more = RFNewEvent (NewEventData -> more) type Reactive a = FreeC ReactiveF a data NewEventData = NewEventData forall a. Tuple (Event a) (a -> Reactive Unit) data Event a = ENever | EMerge (Event a) (Event a) | EFilterJust (Event (Maybe a)) | ECoalesce (a -> a -> a) (Event a) | EOnce (Event a) | ESplit (Event (Array a)) | EVar Int data Behaviour a = BVar Int extractNewEventData :: forall a. NewEventData -> (Tuple (Event a) (a -> Reactive Unit)) extractNewEventData (NewEventData x) = x newEvent :: forall a. Reactive (Tuple (Event a) (a -> Reactive Unit)) newEvent = map extractNewEventData $ liftFC $ RFNewEvent id 

Edit

Also trying out purescript-exists. Makes it possible to define "sample"

RFSample gets added to ReactiveF ...

. . . data ReactiveF more = RFNewEvent (NewEventData -> more) | RFSample (SampleData more) . . . data SampleDataF more a = SampleDataF (Behaviour a) (a -> more) type SampleData more = Exists (SampleDataF more) sample :: forall a. Behaviour a -> Reactive a sample beh = liftFC $ RFSample $ mkExists $ SampleDataF beh id 

Thank you Phil Freeman for your comment.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.