我尝试将benncoded torrent文件(我的玩具项目的一部分来学习Haskell)解析为Haskell中的专用结构:
import qualified Data.ByteString.Char8 as BC
data BEncode = BString BC.ByteString
| BInt Integer
| BList [BEncode]
| BDic [(BEncode, BEncode)] <-- here is the problem I want to make it BDic [(BString, BEncode)]
deriving (Eq,Show)
一切正常,但我想做些小改进 BDic数据构造函数采用(BEncode&lt; - 这是密钥,BEncode,&lt; - 这是值)列表。它过于笼统我想将键限制为只有BStrings,有没有办法做到这一点?
以下是解析器的其余部分:
num::P.Parser String
num = many1 digit
bInt::P.Parser BEncode
bInt = (BInt . read) <$> (char 'i' *> num <* char 'e')
bString :: P.Parser BEncode
bString = do n <- num
_ <- char ':'
BString <$> (P.take (read n))
bList :: P.Parser BEncode
bList = (BList) <$> (char 'l' *> (many1 (bInt <|> bString <|> bList)) <* char 'e')
dicEntry :: P.Parser (BEncode, BEncode)
dicEntry = ((,)<$>bString <*> bencodeParser)
bDic :: P.Parser BEncode
bDic = BDic<$>((char 'd' *> many1 dicEntry <* char 'e'))
bencodeParser :: P.Parser BEncode
bencodeParser = bInt <|> bString <|> bList <|> bDic
答案 0 :(得分:2)
BDic数据构造函数(BEncode&lt; - 这是关键,BEncode,&lt; - 这个 是值)列表。它太笼统我想限制键只是 BStrings,有没有办法做到这一点?
实现这一目标的一种方法是改变结构:
data BStringT = BString BC.ByteString deriving (Eq, Show)
data BEncode = BStringT
| BInt Integer
| BList [BEncode]
| BDic [(BStringT, BEncode)]
deriving (Eq,Show)
通过这种方式,您可以强制它是BStringT
的第一个参数。