3

私は、Edward Kmett による machines モジュールをいじっていますが、あちこちで少し混乱しています。質問をする最良の方法は、おもちゃのユースケースを提供することだと思いました。以下で説明します。

マシン 1 と 2 は、Y 型の 2 つのプロングに配置されています。

マシン 1 は int のリストをパラメータとして取り、それを下流にプッシュします。マシン 2 は、文字のリストをパラメータとして取り、それを下流にプッシュします。

マシン 3 は、 から始まる内部状態を保持しmempty、その後mappends、何らかの条件で Y ベースからいずれかのマシンから受け取る要素 (両方ではない) を保持します。次に、マシン 3 が現在の状態を取得し、ダウンストリームにプッシュします。

マシン 4 は、受け取った要素をコンソールに出力します。

これまでのところ、私はこれを持っています:

y1 :: PlanT k [Int] m ()
y1 = yield

y2 :: PlanT k [Char] m ()
y2 = yield

しかし、y1 と y2 を組み合わせる方法がわかりません。または、Process.hs によってエクスポートされたストック コンビネーターの 1 つを使用するのではなく、状態を非表示にする任意のプロセスをロールします。

提案によると、machines パッケージへのリンク: http://hackage.haskell.org/package/machines

そして、それが何をするかについて非常に高レベルの説明を提供するpdf:https ://dl.dropboxusercontent.com/u/4588997/Machines.pdf

4

1 に答える 1

5

私はマシンの初心者でもあります。これが私の結果です。

import Control.Monad
import Data.Char (intToDigit)
import Data.Machine
import Data.Machine.Plan
import Data.Machine.Source

-- | Produces integers from a list.
m1 :: [Int] -> Source Int
m1 = source

-- | Produces characters from a list.
m2 :: [Char] -> Source Char
m2 = source

-- | Reads a number from its left input. Then reads this many
-- characters from its right input. Outputs the resulting string,
-- together with the number of strings produced so far.
m3 :: Tee Int Char (Int, String)
m3 = construct (loop 0)
  where
    -- `loop` keeps internal state - the count of strings
    -- produced so far.
    loop count = do
        -- Read a number from L.
        n <- awaits L
        -- Read this many characters from L.
        s <- replicateM n (awaits R)
        let count' = count + 1
        -- Output the result.
        yield (count', s)
        loop count'

main = print . run $ tee (m1 [2,3,4,5])
                         (m2 "Lorem ipsum dolor sit amet") m3

ではモノイドを使用していませんm3。代わりに単純な数値を使用しましたが、考え方は同じです。私の例では決定論的な入力が必要なため、Tee代わりに も使用しました。またはから読み取るかどうかを選択します。しかし、同様の目的で使用することはまったく同じです。WyeLRWye

更新:カウントを追跡するState代わりに使用することは確かに可能です。Identity例えば:

m3State :: TeeT (State Int) Int Char (Int, String)
m3State = repeatedly $ do
        n <- awaits L
        s <- replicateM n (awaits R)
        lift (modify (+ 1)) -- increment the counter
        count <- lift get   -- get the counter to output it
        yield (count, s)

main = print . flip evalState 0 . runT $ input m3State

プランで使用repeatedlyする方が、明示的なモナド ループを使用するよりもわずかに高速であると思いますが、この小さな例では、違いはごくわずかだと思います。

または、文字列の数を数えて最後にのみ出力したい場合は、Writer (Sum Int)代わりに を使用できます。完全なコードはこちら

于 2013-06-26T20:14:39.590 に答える