2

Getmonadからある程度のビットを読み取る必要があります。今私のコードは次のようになります

readBits :: Int -> Int -> Get (Word32, Int)
readBits count state = ...

readValue :: Get (Word32, Word32)
readValue = do
   -- read fst bit count 
   (bits1, s0) <- readBits 5 0
   -- read bits1 bits as fst
   (fst, s1) <- readBits bits1 s0
   -- read snd bit count
   (bits2, s2) <- readBits 5 s1
   -- read bits2 bits as snd
   (snd, s3) <- readBits bits2 s2  
   -- flush incomplete byte
   when (s3 /= 0) $ skip 1
   return (fst, snd)

これをある種の状態モナドにラップして、次のようなコードを作成したいと思います。

readBits :: Int -> BitReader Word32
readBits count = ...

runBitReader :: BitReader a -> Get a

readValue :: Get (Word32, Word32) 
readValue = runBitReader $ do
      bits1 <- readBits 5
      fst <- readBits bits1
      bits2 <- readBits 5
      snd <- readBits bits2
      return (fst, snd)

どのような機能を実装する必要がありますか?それらはどのように実装する必要がありますか?

GetとBitGetのソースコードを調べましたが、何が起こっているのか完全には理解していません。

4

1 に答える 1

2

これは、モナド変換子の最も一般的な使用例です。

ほとんどの構造を正しく定義しました。あなたの質問に答えるために

What functions should I implement? 
  • さて、あなたは最初にGetモナドをStateTトランスフォーマーにラップして取得する必要がありますBitReader
  • 現在の状態を取得して状態を保存するためにreadBits使用するための適切な定義を実装する必要があります。getput
  • MonadBitReaderで出力を取得するには、ラップされたコードを実行する必要があります。したがって、を使用Getして定義する必要があります。runBitReaderrunStateT

あなたの次の質問に答えるために。

How should they be implemented?

私は可能な実装を与えました。それを機能させるには、まだいくつかの関数を定義する必要があります。

import Control.Monad.State 
import qualified Control.Monad.State as ST
import Data.Binary 

type BitReader = StateT Int Get

readBits' :: Int -> Int -> Get (Word32, Int)
readBits' = undefined   

readBits :: Int -> BitReader Word32
readBits n = do 
    s0 <- ST.get 
    (a,s1) <- lift $ readBits' n s0
    ST.put s1 
    return a


runBitReader :: BitReader a -> Get a
runBitReader w = do 
    (a,s) <- runStateT w 0
    return a

readValue = do
      fst <- readBits 5
      snd <- readBits 10
      return (fst, snd) 

Getのコードを調べることがどのように役立つかわかりません。あなたは間違った家を探していました。とについて読む必要がありState MonadsますMonad Transformers

モナド変換子の詳細については、こちらをご覧ください。

于 2012-09-13T16:40:01.910 に答える