монадные трансформеры и укладка нескольких монад - PullRequest
2 голосов
/ 21 января 2010

У меня есть функция f с подписью f :: [a] -> StateT Int Reader b [c] и f' с подписью f' :: a -> StateT Int Reader b [c]

Вычисление в f (очень упрощенное) выглядит так:

f [] = return []
f (s:st) = f' s >>= \x ->
           f st >>= \y ->
           return $ ...

И вместо ... Я хотел бы вернуть [c] часть x ++ [c] часть y с монадой, обернутой вокруг.
Есть ли возможность добиться этого, не распаковывая вручную x и y и снова вручную складывая результат? Нужна ли мне монада List в нижней части моего стека монад, чтобы получить простой код? Read Monad, очевидно, не является экземпляром класса MonadPlus.

Ответы [ 3 ]

3 голосов
/ 21 января 2010

Я не понимаю, что вы имеете в виду, развернув x и y.

последняя строка будет

return (x ++ y)

Я неправильно понимаю, что вы хотите?

2 голосов
/ 22 января 2010

Вы также можете просто определить

f = fmap concat . mapM f'

(mapM f' xs создает значение типа m [[c]], где xs :: [a] и m = StateT Int (Reader b), а затем fmap concat объединяет списки "внутри монады".)

1 голос
/ 21 января 2010

И f' s, и f st являются значениями в одной монаде, а именно StateT Int Reader b.Итак, у вас уже есть x :: [c] и y :: [c], и вам просто нужно написать return (x ++ y), как сказал Дейв Хинтон.

...