Я немного озадачен этим сообщением об ошибкеКак справиться с побочными эффектами с Eff Монады
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
и Either
? Это, похоже, только в случае создания экземпляра класса типа IsForeign. sideeffect
работает счастливо в main
- конечно главная имеет подпись, которая гласит его использование в Eff Монада
> :t Chapter2.main
Compiling Chapter2
forall t20. Control.Monad.Eff.Eff (trace :: Debug.Trace.Trace | t20) Prelude.Unit
Хорошо, да, это правильно - но это не то, что я хочу. Я не хочу, чтобы блок 'do' выводил тип' Eff ... ', поскольку я возвращаю' return $ S "Test" '. Итак, как я могу сказать компилятору не делать этого? Или даже лучше, как я могу назвать побочный эффект без изменения подписи 'read' – robkuz
Вы можете использовать' Control.Monad.Eff.runPure <<< Control.Monad.Eff.Unsafe.unsafeInterleaveEff', который является функцией типа 'forall eff a. Eff eff a -> a', если вам действительно нужно выполнять действия Eff в таких местах. Но я бы обескураживал это - это подрывная система типа. Вся причина, по которой существует система типов, заключается в том, чтобы дать вам надежные гарантии того, что некоторые части вашей программы не выполняют, и таким образом, подрывая систему типов, вы ослабляете эти гарантии. – hdgarrood
@hdgarrood: * вздох * Я знаю - но тогда. Как просто добавить инструкции трассировки в свою программу, не меняя подписи во всей моей цепочке вызовов. Это была моя первоначальная проблема. Если вы замените 'v <- sideeffect 42' в моем вышеприведенном коде просто« trace »Hello», у вас будет такая же проблема (очевидно, так как трассировка является побочным эффектом). Но трассировка настолько распространена ... – robkuz