Monad Transformers e empilhamento de várias mônadas
-
22-09-2019 - |
Pergunta
Eu tenho função f
com assinatura f :: [a] -> StateT Int Reader b [c]
, e f'
com assinatura f' :: a -> StateT Int Reader b [c]
O cálculo em f (muito simplificado) parece assim:
f [] = return []
f (s:st) = f' s >>= \x ->
f st >>= \y ->
return $ ...
E no lugar do ... eu gostaria de devolver o [c]
parte de x
++
a [c]
parte de y
Com as coisas da Mônada enroladas.
Existe a possibilidade de conseguir isso sem desembrulhar manualmente x
e y
e montar o resultado manualmente novamente? Preciso de uma mônada de lista na parte inferior da minha mônada para obter código simples? Obviamente, a Mônada do Leitor não é uma instância da classe Monadplus.
Solução
Eu não entendo o que você quer dizer com desembrulhar x
e y
.
Eu teria a última linha como
return (x ++ y)
Eu entendi mal o que você quer?
Outras dicas
Você também pode simplesmente definir
f = fmap concat . mapM f'
(mapM f' xs
produz um valor do tipo m [[c]]
, Onde xs :: [a]
e m = StateT Int (Reader b)
, e depois fmap concat
Concatena as listas "dentro da mônada".)
Ambos f' s
e f st
são valores em uma mônada, ou seja, StateT Int Reader b
. Então você já tem x :: [c]
e y :: [c]
E você só precisa escrever return (x ++ y)
, como Dave Hinton disse.