11

attoparsecIResultからモナドをいくつかの断片に分解しようとしています。こちらですIResult

data IResult t r = Fail t [String] String
                 | Partial (t -> IResult t r)
                 | Done t r

これは、効果、「偏見」、および失敗の組み合わせであるべきだと感じています。失敗がただのこととして表される場合Either ([String], String)、偏見はあるかもしれません

data Partiality t a = Now a | Later (t -> Partiality t a)

instance Monad (Partiality t) where
  return = pure
  (Now a) >>= f = f a
  (Later go) >>= f = Later $ \t -> go t >>= f

class MonadPartial t m where
  feed  :: t -> m a -> m a
  final :: m a -> Bool

instance MonadPartial t (Partiality t) where
  feed _ (Now a) = Now a
  feed t (Later go) = go t
  final (Now _) = True
  final (Later _) = False

( を使用すると、Danielsson の論文からその名前が付けられますPartiality ())

Partialityベースモナドとして使えますが、PartialityTモナドトランスフォーマーはありますか?

4

1 に答える 1

12

確かにあります!あなたの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し、基本モナドでアクションを呼び出します。無料のモナド変換子は自動的に任意のファンクターのモナドおよびモナド変換子になるため、 MonadandMonadTransインスタンスを無料で取得します。PartialityT

上記のプログラムを次のように実行します。

>>> runPartialityT [1..] printer
1
2
3
...

フリーモナドトランスフォーマーについて書いたこの投稿を読むことをお勧めします。しかし、無料のモナド変換子の新しい公式ホームはfreeパッケージです。

また、効果的なインクリメンタル パーサーをお探しの場合はpipes-parse、数日以内にパッケージとしてリリースする予定です。現在のドラフトはこちらで確認できます。

于 2013-03-04T04:18:13.143 に答える