0

長さがエンコードされたバイナリ ストリームを解析しており、このコードをコンパイルしようとしています。コンビナトレントコード ( https://github.com/jlouis/combinatorrent/blob/master/src/Protocol/Wire.hs ) は非常に役に立ちましたが、今は行き詰まっています。return ステートメントで frame_length を使用するにはどうすればよいですか?

data FrameCont = FINAL | MORE | BADCONT
    deriving (Show, Eq)
frame_cont 0x00      = FINAL
frame_cont 0x01      = MORE
frame_cont otherwise = BADCONT

data FrameSize = Small Word8 | Jumbo B.ByteString
    deriving (Show)

get_fc = do
    raw_cont <- AP.anyWord8
    guard((frame_cont raw_cont) /= BADCONT) AP.<?> "State must be either MORE or FINAL"
    return raw_cont

parser = do
    frame_length <- AP.anyWord8
    case frame_length of
        0x255      ->  return (Jumbo <$> AP.take 8, get_fc, AP.take (fromIntegral frame_length))
        otherwise  ->  return (Small otherwise, get_fc, AP.take (fromIntegral frame_length))

また、Word64 にパス (AP.take 8) を使用するにはどうすればよいですか?

4

1 に答える 1

1

パーサーの2つのブランチの最初のコンポーネントには異なるタイプがあり、ブランチは、、Jumboもう1Parser FrameSizeつはプレーンFrameSizeです。parserタイプがである必要がある場合はParser (Parser FrameSize, Parser Word8, Parser ByteString)、2番目のブランチの最初のコンポーネントをに変更するだけreturn (Small otherwise)です。ただし、必要になる可能性が高いparser :: Parser (FrameSize, Word8, ByteString)ため、内で他のパーサーを実行する必要がありますparser。おもう

parser = do
    frame_length <- AP.anyWord8
    frame_size <- case frame_length of
                    0xFF -> Jumbo <$> AP.take 8   -- 0xFF == 255, 0x255 == 597
                    flen -> return (Small flen)
    fc <- get_fc
    bs <- AP.take (fromIntegral frame_length)
    return (frame_size, fc, bs)

少なくともあなたが望むものに近いです。

スタイルに関する注意:キャメルケースとunderscore_separatedの単語を組み合わせて、どちらか一方に落ち着かせてください(Haskellの主なスタイルはキャメルケースなので、それを選択することをお勧めします)。

于 2011-10-26T20:12:53.340 に答える