haskell中的简单解析器

时间:2015-02-07 19:16:39

标签: haskell

我尝试将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

1 个答案:

答案 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的第一个参数。