2016-01-04 11 views
6

ı bu (belki saptırmak) var demek kod parçasıdır etrafında döşeme Let bir ExceptT içine Either kaldırma? Either StringMonadError örneğinden beri bir şekilde olması gerektiğini hissediyorum. asansör Ya ExceptT otomatik

Ben kendi kaldırma işlevi yazdı:

liftEither :: (Monad m, MonadError a (Either a)) => Either a b -> ExceptT a m b 
liftEither = either throwError return 

Ama zaten ExceptT monad trafonun içine çalışıyorum beri bana bu hala yanlış geliyor.

Burada yanlış olan ne yapıyorum? Kodumu farklı şekilde yapılandırmalı mıyım?

+1

Ne ExceptT 'hakkında. return'? 'ExceptT = ExceptT (m (ya e a)), ', böylece de return' için' ES (ya dize Kullanıcı) ve 'ExceptT' (yapıcı/fonksiyonu olarak) ExceptT dize IO User'' için alır. – ibotty

cevap

7

Sen

parseUser :: (MonadError String m) => String -> m User 

için parseUser 'ın tipini genelleme yapabiliriz ve daha sonra m ~ Either String de ve m ~ ExceptT String m' herhangi bir manuel kaldırma olmadan (Monad m' yalnızca) gerekli hem de çalışacak.

yolu temelde parseUser 'ın tanımı throwError ile return ve Left ile Right değiştirmektir yapmak.

+2

"MonadError String m' ghc" nin contraint için 'FlexibleContexts' uzantısına ihtiyacı olduğunu unutmayın (bkz. Http://stackoverflow.com/a/22795830/905686). – user905686