I try to parse benncoded torrent file (part of my toy project to learn Haskell) into a dedicated structure in 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)
Everything works fine but I would like to make small improvement.
BDic data constructor takes (BEncode <- this is key, BEncode ,<- this is value) list. It's too general I would like to limit keys to be only BStrings, is there a way to do this?
Here is rest of the parser:
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