3
votes

I'm still learning Haskell and need help with the type inference please!

Using packages SDL and Yampa I get the following type signature from FRP.Yampa.reactimate:

(Bool -> IO (DTime, Maybe a))

and I want to use it for:

myInput :: Bool -> IO (DTime, Maybe [SDL.Event])
myInput isBlocking = do
    event <- SDL.pollEvent
    return (1, Just [event])
...
reactimate myInit myInput myOutput mySF

but it says

Couldn't match expected type `()'
       against inferred type `[SDL.Event]'
  Expected type: IO (DTime, Maybe ())
  Inferred type: IO (DTime, Maybe [SDL.Event])
In the second argument of `reactimate', namely `input'
In the expression: reactimate initialize input output process

I thought Maybe a allows me to use anything, even a SDL.Event list? Why is it expecting Maybe () when the type signature is actually Maybe a? Why does it want an empty tuple, or a function taking no arguments, or what is () supposed to be?

1

1 Answers

8
votes

The full type signature of reactimate is

IO a                               -- # myInit
 -> (Bool -> IO (DTime, Maybe a))  -- # myInput
 -> (Bool -> b -> IO Bool)         -- # myOutput
 -> SF a b                         -- # mySF
 -> IO ()

The same a and b must match, that means if your myInput has type Bool -> IO (DTime, Maybe [SDL.Event]), then all other a must also be [SDL.Event]. Hence, to match the types, you need to ensure

 myInit :: IO [SDL.Event]     -- # **not** IO ().
 mySF :: SF [SDL.Event] b

BTW, () is the unit type.