Chyba brakuje podstawowe zrozumienie transformatorów monady, ponieważ uważam, że ja pisząc ten kod:Podnieś wartość błędu do transformatora monada ErrorT
import Control.Monad.Identity
import Control.Monad.Error
liftError :: Either String Int -> ErrorT String Identity Int
liftError x = do case x of
Right val -> return val
Left err -> throwError err
gateway :: Bool -> ErrorT String Identity Int
gateway = liftError . inner
inner :: Bool -> Either String Int
inner True = return 5
inner False = throwError "test"
Chociaż to działa, myślę, że może to być zrobione więcej elegancko. W szczególności szukam zamiennika liftError
, co moim zdaniem nie powinienem sam określać.
Jaki byłby najprostszy sposób, aby gateway
i inner
współpracować bez zmiany ich typu?
Okej, więc, mówiąc dokładniej, muszę napisać ręczną funkcję podnoszenia, jeśli chcę zostawić typy takimi, jakimi są? To tylko dla mojego zrozumienia. BTW niestety nie mogę dzisiaj głosować:/Otrzymasz głos jutro :) –
Bez zmiany typów możesz użyć 'ErrorT. return' w miejscu twojej funkcji 'liftError'. Możesz także użyć wewnętrznej wersji bardziej ogólnej i ujawnić tylko kopię "wewnętrznego" z zastrzeżonym typem. – hammar
To 'ErrorT. return' było dokładnie tym, czego szukałem. Jak już wspomniałem, nie ma to nic wspólnego z żadnym prawdziwym kodem, po prostu chcę zrozumieć pojęcie transformatorów monadowych :) –