2

As the title says, I am trying to use logShow inside of my handleAction function. I imported the Effect.Console (logShow) and tried to use it like this, everytime a button is clicked:

handleAction ∷ forall o m. Action → H.HalogenM State Action () o m Unit
handleAction = case _ of
  Update -> do
    logShow "Hello"
    H.modify_ \st -> st { field3 = st.field3 + 1 }

But I only get the following Error, and I don't understand very much, as I am very new to purescript and functional programming at all.

Could not match type

    Effect

  with type

    HalogenM
      { field1 :: Int
      , field2 :: Int
      , field3 :: Int
      }
      Action
      ()
      o0
      m1

while trying to match type Effect t2
  with type HalogenM
              { field1 :: Int
              , field2 :: Int
              , field3 :: Int
              }
              Action
              ()
              o0
              m1
              Unit
while checking that expression (discard (logShow "Hello")) (\$__unused -> modify_ (\st -> ... ))
  has type HalogenM
             { field1 :: Int
             , field2 :: Int
             , field3 :: Int
             }
             Action
             ()
             o0
             m1
             Unit
in value declaration handleAction

where m1 is a rigid type variable
        bound at (line 77, column 16 - line 80, column 51)
      o0 is a rigid type variable
        bound at (line 77, column 16 - line 80, column 51)
      t2 is an unknown type
PureScript(TypesDoNotUnify)

I am glad about any clue.

  • 2
    You can use [traceM](https://pursuit.purescript.org/packages/purescript-debug/4.0.0/docs/Debug.Trace#v:traceM). Or `H.liftEffect $ logShow "hello"` – rnons Sep 04 '19 at 07:13

1 Answers1

2

I'm not an expert in PS but I'll try my best to answer it. So please correct me if I'm wrong:

logShow type signature is MonadEffect m => Show a => a -> m Unit, means that the caller of this function should have an instance of or be constrained by MonadEffect.

In your case, handleAction has a type signature of forall o m. Action → H.HalogenM State Action () o m Unit and you call logShow inside it. Your m here doesn't describe any particular monad while as we knew already, the caller of logShow should be constrained by MonadEffect.


There are a couple of ways to solve this:

  1. You can add MonadEffect constraint to your handleAction type signature like so

    forall o m. (MonadEffect m) => Action → H.HalogenM State Action () o m Unit
    

    This should work since HalogenM has instance of MonadEffect as long as your m also has MonadEffect instance. See here

  2. Change your m to Aff as Aff has instance of MonadEffect. IIRC, Halogen requires your m to be or has an instance of Aff

  3. Or you could use your own monad stack that has an instance of Aff as you can see in Thomas' great repository here

EDIT: The explanation above assumes you import logShow from Effect.Class.Console

But if you're using logShow from Effect.Console which has type signature Show a => a -> Effect Unit, then we need some function that converts the Effect monad to your m (this function should have type sig Effect a -> m a). And liftEffect is exactly what you're looking for.

handleAction :: forall o m. (MonadEffect m) => Action → H.HalogenM State Action () o m Unit
handleAction _ = do
  liftEffect $ logShow "something"
  ...

Hope this helps :)

Jihad Waspada
  • 1,133
  • 1
  • 11
  • 16