2

Я имею функцию 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 и вручную снова собрать результат? Нужен ли мне Монада списка внизу моего стека монады, чтобы получить простой код? Reader Monad, очевидно, не является экземпляром класса MonadPlus.

ответ

3

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

я бы последнюю линию как

return (x ++ y) 

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

+0

Ах да, вы 're right - thx :) Я перепутал тип базовой монады и тип результата вычисления. – haselhorstk

1

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

2

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

f = fmap concat . mapM f' 

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