您的代码片段远非自包含(特别Packet
是缺少导入和数据类型的定义),但您似乎使事情过于复杂。
首先,为一位整数定义解析器。然后,将后者用作两位整数解析器的构建块。之后,使用应用运算符来组合这两个解析器并为您的自定义Packet
数据类型定义一个解析器。见下文。
请注意,您不需要 monad 的全部功能;在这里,应用解析就足够了。
-- test_attoparsec.hs
{-# LANGUAGE OverloadedStrings #-}
import Control.Applicative ((<$>))
import Data.Attoparsec.Text
import Data.Char
data Packet = Std {-# UNPACK #-} !Int
{-# UNPACK #-} !Int
deriving (Show)
stdK :: Parser Packet
stdK = char '1' *> (Std <$> twoDigitInt <*> oneDigitInt)
twoDigitInt :: Parser Int
twoDigitInt = timesTenPlus <$> oneDigitInt <*> oneDigitInt
where
timesTenPlus x y = 10 * x + y
oneDigitInt :: Parser Int
oneDigitInt = digitToInt <$> digit
GHCi 中的测试:
λ> :l test_attoparsec.hs
[1 of 1] Compiling Main ( test_attoparsec.hs, interpreted )
Ok, modules loaded: Main.
λ> :set -XOverloadedStrings
λ> parseOnly stdK "1341"
Right (Std 34 1)
λ> parseOnly stdK "212"
Left "1: Failed reading: satisfyWith"