I am learning how to use the Haskell FRP library called Reactive Banana, and also fairly new to Haskell in general. Currently I am creating a function that will take a network as a parameter, and in the function body do some initialization before compiling the network and going through its event loop, but I am having trouble with Haskell being unable to deduce what I am trying to do.
Here's a reduced version of the code
{-# LANGUAGE ScopedTypeVariables #-}
module Main where
import qualified Reactive.Banana as R
import qualified Reactive.Banana.Frameworks as RF
main = start setupNetwork
start :: forall t. RF.Frameworks t => R.Moment t () -> IO ()
start network = do
net <- RF.compile $ network
RF.actuate net
keyAddHandler = RF.newAddHandler
setupNetwork :: forall t. RF.Frameworks t => R.Moment t ()
setupNetwork = do
(addKey, firekey) <- RF.liftIO keyAddHandler
return ()
The exact error that I am getting is this.
Test.hs:11:25:
Could not deduce (t ~ t1)
from the context (RF.Frameworks t)
bound by the type signature for
start :: RF.Frameworks t => R.Moment t () -> IO ()
at Test.hs:(10,1)-(12,18)
or from (RF.Frameworks t1)
bound by a type expected by the context:
RF.Frameworks t1 => R.Moment t1 ()
at Test.hs:11:12-31
`t' is a rigid type variable bound by
the type signature for
start :: RF.Frameworks t => R.Moment t () -> IO ()
at Test.hs:10:1
`t1' is a rigid type variable bound by
a type expected by the context: RF.Frameworks t1 => R.Moment t1 ()
at Test.hs:11:12
Expected type: R.Moment t1 ()
Actual type: R.Moment t ()
In the second argument of `($)', namely `network'
In a stmt of a 'do' block: net <- RF.compile $ network
Searching the internet leads me to believe that types between the framework in the start function and the framework in the setupNetwork function are not considered the same type.
Is there anyway to get the types to match up?
It's been a while since I've played around with reactive-banana (or anything else that pushes the type system so much), but I think the type signature should be something more like
start :: (forall t. RF.Frameworks t => R.Moment t ()) -> IO ()
(i.e. You need to add parentheses in the right places.)
You'll need {-# LANGUAGE RankNTypes #-}
as well.