Ответ 1
Конечно! Ваша монада Partiality
- свободная монада:
import Control.Monad.Free -- from the `free` package
type Partiality t = Free ((->) t)
... и соответствующий PartialityT
является свободным монадным трансформатором:
import Control.Monad.Trans.Free -- also from the `free` package
type PartialityT t = FreeT ((->) t)
Здесь приведен пример программы, показывающей, как вы ее используете:
import Control.Monad
import Control.Monad.Trans.Class
import Control.Monad.Trans.Free
type PartialityT t = FreeT ((->) t)
await :: (Monad m) => PartialityT t m t
await = liftF id
printer :: (Show a) => PartialityT a IO r
printer = forever $ do
a <- await
lift $ print a
runPartialityT :: (Monad m) => [a] -> PartialityT a m r -> m ()
runPartialityT as p = case as of
[] -> return ()
a:as -> do
x <- runFreeT p
case x of
Pure _ -> return ()
Free k -> runPartialityT as (k a)
Мы создаем бесплатный трансформатор монады с помощью команды await
для запроса новых значений и lift
для вызова действий в базовой монаде. Мы получаем экземпляры Monad
и MonadTrans
для PartialityT
бесплатно, потому что свободный монадный трансформатор автоматически является монадным и монадным трансформатором для любого заданного функтора.
Мы запускаем вышеуказанную программу следующим образом:
>>> runPartialityT [1..] printer
1
2
3
...
Я рекомендую вам прочитать этот пост, который я написал о свободных монадных трансформаторах. Тем не менее, новым официальным домом бесплатного монада-трансформатора является пакет free
.
Кроме того, если вы ищете эффективный инкрементный парсер, я собираюсь выпустить его как пакет pipes-parse
в течение нескольких дней. Вы можете проверить текущий проект здесь.