2017-04-14 38 views
1

我有得到一个问题,下面来编译:liftEff影响排式统一

module ContrivedExample where 

import Prelude 
import Data.Either (Either(..)) 
import Control.Monad.Eff (Eff) 
import Control.Monad.Eff.Exception (EXCEPTION, throw) 
import Control.Monad.Eff.Console (CONSOLE, log) 
import Control.Monad.Eff.Class (liftEff) 
import Control.Monad.Aff (launchAff) 
import Control.Monad.Aff.Console (log) as A 

contrivedExample :: forall e. Either String String -> Eff (exception :: EXCEPTION, console :: CONSOLE | e) Unit 
contrivedExample a = do 
     _ <- launchAff do 
     _ <- A.log "yay" 
     liftEff $ case a of 
      Left e -> log e 
      Right a -> throw a 
     pure unit 

我得到这个错误:

Could not match type 

    (console :: CONSOLE 
    | e3 
    ) 

    with type 

    (exception :: EXCEPTION 
    , console :: CONSOLE 
    | t2 
    ) 

如果我从影响行删除异常,我得到在Either的另一端出现错误。有没有更好的选择liftEff或某种方式我可以统一类型?

回答

1

按照launchAffdocumentation

Converts the asynchronous computation into a synchronous one. All values are ignored, and if the computation produces an error, it is thrown.

Catching exceptions by using catchException with the resulting Eff computation is not recommended, as exceptions may end up being thrown asynchronously, in which case they cannot be caught.

If you do need to handle exceptions, you can use runAff instead, or you can handle the exception within the Aff computation, using catchError (or any of the other mechanisms).

我相信你无法抛出异常里面launchAff,除非你也追上他们相同的计算内。否则,您只能在launchAff计算内执行其他效果。