Fresheyeball
Fresheyeball

Reputation: 30015

PureScript Type Error is hard to understand

This compiles

foo ma = case ma of
  [Just a] -> newRVar 0 >>= a

view                :: forall a eff. 
                       M.Map String (Linker Number a eff) -> 
                       String -> 
                       Eff (reactive :: Reactive | eff) Unit
view         m yaml = case parseYAML yaml           of
  Right (View xs)  -> case (flip M.lookup) m <$> xs of
    (as)       -> foo as

This does not

foo ma = case ma of
  Just a -> newRVar 0 >>= a

view                :: forall a eff. 
                       M.Map String (Linker Number a eff) -> 
                       String -> 
                       Eff (reactive :: Reactive | eff) Unit
view         m yaml = case parseYAML yaml           of
  Right (View xs)  -> case (flip M.lookup) m <$> xs of
    (as)       -> foo <$> as

with the following error:

 Cannot unify Control.Monad.Eff.Eff (reactive :: Control.Reactive.Reactive | u8437) u8438 with Prelude.Unit.

Why?

Upvotes: 0

Views: 311

Answers (1)

gb.
gb.

Reputation: 4649

The error message is telling you that you're putting an Control.Monad.Eff.Eff (reactive :: Control.Reactive.Reactive | u8437) u8438 where a Unit should go.

Does foo have an type declaration? It probably won't work without one regardless of what you're doing in view, because of the current lack of typeclass constraint inference.

In the second case the type is:

foo :: forall a eff. Maybe a -> Eff (reactive :: Control.Reactive.Reactive | eff) a

The type of (<$>) is

(<$>) :: forall f a b. (Functor f) => (a -> b) -> f a -> f b

And the type of as will be Maybe (Linker Number a eff), so if you start substituting types you can see pretty quickly where it goes wrong:

a ~ Maybe (Linker Number a1 eff)
b ~ Eff (reactive :: Control.Reactive.Reactive | eff) (Linker Number a1 eff)
f ~ Maybe

So the f b result type of foo <$> as is:

Maybe (Eff (reactive :: Control.Reactive.Reactive | eff) (Linker Number a1 eff))

Upvotes: 1

Related Questions