如何在 Halogen 5 的 handleAction 函数中使用 logShow

How to use logShow inside the handleAction function in Halogen 5

正如标题所说,我正在尝试在我的 handleAction 函数中使用 logShow。 我导入了 Effect.Console (logShow) 并尝试像这样使用它,每次单击按钮时:

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 }

但我只得到以下错误,而且我不太了解,因为我对纯脚本和函数式编程非常陌生。

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)

我很高兴有任何线索。

我不是 PS 方面的专家,但我会尽力回答。所以如果我错了请纠正我:

logShow类型签名是MonadEffect m => Show a => a -> m Unit,意味着这个函数的调用者应该有一个MonadEffect.

的实例或者受其约束

在您的例子中,handleAction 的类型签名为 forall o m. Action → H.HalogenM State Action () o m Unit,您在其中调用 logShow。您的 m 在这里没有描述任何特定的单子,而正如我们已经知道的那样, logShow 的调用者应该受到 MonadEffect.

的约束

有几种方法可以解决这个问题:

  1. 您可以像这样将 MonadEffect 约束添加到您的 handleAction 类型签名中

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

    这应该有效,因为 HalogenMMonadEffect 的实例,只要 你的 m 也有 MonadEffect 实例。参见 here

  2. 将您的 m 更改为 Aff,因为 Aff 具有 MonadEffect 的实例。 IIRC,Halogen 要求您的 m 是或具有 Aff

  3. 的实例
  4. 或者你可以使用你自己的 monad 堆栈,它有一个 Aff 的实例,正如你在 Thomas' great repository here
  5. 中看到的

编辑:上面的解释假设您从 Effect.Class.Console

导入 logShow

但是,如果您使用的 Effect.Console 中的 logShow 具有类型签名 Show a => a -> Effect Unit,那么我们需要一些函数将 Effect monad 转换为您的 m(此函数的类型应为 sig Effect a -> m a)。 liftEffect 正是您要找的。

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

希望这对您有所帮助:)