Haskell Netwire - Type errors
frp, functional-programming, haskell, netwire
Solution
Edit: Here's a complete, compiling, running solution to this problem:
module Main (
main
) where
import Prelude hiding ((.), id)
import qualified Prelude as Prelude
import Control.Wire
import Control.Wire.Interval
main :: IO ()
main = testWire clockSession_ (withoutErrors forYeah)
yeah :: Monad m => Wire s e m a String
yeah = pure "yes"
forYeah :: (Num t, HasTime t s, Monoid e, Monad m) => Wire s e m a String
forYeah = for 3 . yeah
-- This just is an easy way to specify to use () as the type for errors in testWire
withoutErrors :: Wire s () m a b -> Wire s () m a b
withoutErrors = Prelude.id
Here's the original answer, that discussed why we should change the type of `yeah`, and then the necessary changes to the type of `forYeah`:
Change the type of `yeah` to `Monad m => Wire s e m a String`. `Monad m => (Wire s e m a)` has an `Applicative` instance , so `pure` should exist without specifying that the second type argument to `Wire` in `yeah`'s type is `()`.
Note: I don't use netwire and I haven't tried compiling this. I've only looked at the types in the documentation.
Edit: You probably also need to change the type of `forYeah`.
`Wire` also has a `Category` instance:
Monad m => Category (Wire s e m)
`Category`'s `.` operator has the following type:
(.) :: cat b c -> cat a b -> cat a c
So for `Wire`s it is:
(.) :: Monad m => Wire s e m b c -> Wire s e m a b -> Wire s e m a c
`for` has the following type:
for :: (HasTime t s, Monoid e) => t -> Wire s e m a a
So `for 3` would have a type like `(HasTime Int s, Monoid e) => Wire s e m a a`. Combined with yeah's type of `Monad m => Wire s e m a String`, `for 3 . yeah` would have a type like
(HasTime Int s, Monoid e, Monad m) => Wire s e m a String
So we could probably change the type of `forYeah` to:
forYeah :: (HasTime Int s, Monoid e, Monad m) => Wire s e m a String
Edit: Even better type for `forYeah`
Since an integer numeral (without a decimal point) is actually equivalent to an application of fromInteger to the value of the numeral as an Integer, and `fromInteger :: (Num a) => Integer -> a`, the literal `3` actually has type `Num t => t`. The best type we can choose is therefore probably:
forYeah :: (Num t, HasTime t s, Monoid e, Monad m) => Wire s e m a String
Problem
I have just started using netwire and I'm having trouble with the very basics. The following code works fine for me: ``` main :: IO () main = testWire clockSession_ (for 3 . yeah) yeah :: Monad m => Wire s () m a String yeah = pure "yes" ``` But this does not: ``` main :: IO () main = testWire clockSession_ forYeah forYeah :: (Show b, Show e) => Wire s e Identity a b forYeah = for 3 . yeah ``` fails with error: ``` Could not deduce (b ~ [Char]) from the context (Show b, Show e) bound by the type signature for forYeah :: (Show b, Show e) => Wire s e Identity a b at /home/fiendfan1/workspace/Haskell/Haskell-OpenGL/src/Main.hs:12:12-54 `b' is a rigid type variable bound by the type signature for forYeah :: (Show b, Show e) => Wire s e Identity a b at /home/fiendfan1/workspace/Haskell/Haskell-OpenGL/src/Main.hs:12:12 Expected type: Wire s e Identity a b Actual type: Wire s () Identity a String In the second argument of `(.)', namely `yeah' In the expression: for 3 . yeah In an equation for `forYeah': forYeah = for 3 . yeah ``` So I changed it to: ``` forYeah :: Show e => Wire s e Identity a String ``` which gives me the error: ``` Could not deduce (e ~ ()) from the context (Show e) bound by the type signature for forYeah :: Show e => Wire s e Identity a String at /home/fiendfan1/workspace/Haskell/Haskell-OpenGL/src/Main.hs:12:12-49 `e' is a rigid type variable bound by the type signature for forYeah :: Show e => Wire s e Identity a String at /home/fiendfan1/workspace/Haskell/Haskell-OpenGL/src/Main.hs:12:12 Expected type: Wire s e Identity a String Actual type: Wire s () Identity a String In the second argument of `(.)', namely `yeah' In the expression: for 3 . yeah In an equation for `forYeah': forYeah = for 3 . yeah ``` Changing it to: ``` forYeah :: Wire s () Identity a String ``` Gives the following error: ``` No instance for (HasTime Integer s) arising from a use of `for' Possible fix: add an instance declaration for (HasTime Integer s) In the first argument of `(.)', namely `for 3' In the expression: for 3 . yeah In an equation for `forYeah': forYeah = for 3 . yeah ``` Can someone explain why this happens and how I can fix my second code example?