2

正如标题所说,我正在尝试在我的 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)

我很高兴有任何线索。

4

1 回答 1

2

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

logShow类型签名是MonadEffect m => Show a => a -> m Unit, 意味着这个函数的调用者应该有一个 的实例或受其约束MonadEffect

在你的情况下,handleAction有一个类型签名,forall o m. Action → H.HalogenM State Action () o m UnitlogShow在里面调用。你的m这里没有描述任何特定的单子,而我们已经知道,调用者logShow应该受MonadEffect.


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

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

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

    这应该有效HalogenMMonadEffect 因为只要m也有实例,就有MonadEffect实例。看这里

  2. 将您的实例更改m为. IIRC,卤素要求你是或有一个实例AffAffMonadEffectmAff

  3. Aff或者您可以使用您自己的 monad 堆栈,该堆栈具有您可以在Thomas 的出色存储库中看到的实例

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

但是,如果您使用logShowfrom Effect.Consolewhich 具有类型 signature Show a => a -> Effect Unit,那么我们需要一些将Effectmonad 转换为您的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"
  ...

希望这可以帮助 :)

于 2019-09-18T10:15:40.717 回答