Organização de mônadas - transformando a aplicação de um transformador de mônada em mônada de tipo novo
Estou tentando tirar, por exemplo.ExceptT a (StateT A M)
, para algum tipo de concretoA
e mônadaM
e envolva-os nas minhas novas mônadas personalizadas.
Primeiro eu identifiquei queStateT A M
aparece frequentemente em outros contextos e, portanto, decidi que seria melhor agrupar isso sozinho em uma mônadaM1
e depois embrulheExceptT a M1
para dentroM2
.
A propriedade desejada é fazerM1
eM2
instâncias deMonadState
e a classe deM
(vamos assumir que é chamadoMyMonadClass
) Além dissoM2
deve ser uma instância deMonadError
.
Primeiro, comecei com sinônimos de tipo simples:
type MyState = StateT A M
type MyBranch a = ExceptT a MyState
então pensei em primeiro esboçar as declarações da instância (sem implementar a instância) e foi aí que fiquei preso pela primeira vez.instance MonadState A (MyState)
parecia não ser a sintaxe correta. Eu pensei que teria que criarnewtype MyState' a = StateT a M
e depoistype MyState = MyState A
(Não é possível usar extensões de idioma quando não for necessário).
No entanto, uma vez que comecei a converter os sinônimos emnewtype
declarações comecei a perder a conexão com oStateT A M
eExceptT ...
tipos.
newtype MyState' s a = MyState' { runMyState :: s -> (s, a) }
type MyState = MyState' A
newtype MyBranch e a = MyBranch { runMyBranch :: MyState (Either e a) }
Agora, os transformadores já implementados desapareceram e acho que estou tentando fazer algo que não faz muito sentido. Portanto, minha pergunta é: como envolver corretamente esse tipo de comportamento em novas mônadas compostas que tornam as camadas acessíveis por baixo, para evitar levantamentos desnecessários e manter as coisas claras e bem organizadas.