如何使用Eff Monad处理副作用

时间:2015-05-25 20:30:16

标签: monads purescript

我对此错误消息感到有点难过

myDataGrid.ItemsSource = myViewModel.myDataTable.DefaultView;

这是此代码的结果

Warning: Error in module Chapter2:
Error in value declaration unionIsForeign:
Error checking that type
  Control.Monad.Eff.Eff (trace :: Debug.Trace.Trace | u8717) u8715
subsumes type
  Data.Either.Either Data.Foreign.ForeignError Chapter2.Union
Error at src/Chapter2.purs line 16, column 18 - line 20, column 1:
  Cannot unify type
    Control.Monad.Eff.Eff
  with type
    Data.Either.Either

为什么需要统一module Chapter2 where import Debug.Trace import Data.Foreign import Data.Foreign.Class import Control.Monad.Eff sideeffect :: forall e. Number -> Eff (trace :: Trace | e) Number sideeffect v = return v data Union = S String instance unionIsForeign :: IsForeign Union where read value = do v <- sideeffect 42 return $ S "Test" main = do trace "Test" Eff? 这似乎只是在实例化IsForeign的类型类时的情况。 Eithersideeffect中愉快地运行 - 当然主要有一个签名,表明其使用Eff Monad

main

1 个答案:

答案 0 :(得分:1)

关键部分是:

来自Data.Foreign.Class

class IsForeign a where
  read :: Foreign -> F a

Data.Foreign

type F = Either ForeignError

因此,您的read函数的声明返回类型为Either ForeignError Union

但由于您使用的返回类型为sideeffect的{​​{1}},因此在do块中,do块的推断类型为Eff (trace :: Trace | e) Number值。

也就是说,您尝试从必须返回Eff ...的内容返回Eff ...并且编译器正在抱怨,因为它无法将Either ...与{{1}统一起来}}