HaskellでBitTorrentクライアントを作りたい
Haskellで何か作りたい。でも何か作れるほどHaskellわからない。
と思ってたらBitTorrentクライアントのチュートリアルっぽいものを見つけたので、せっかくだし作ってみようという話です。
以前の記事で作っていたBencodeのパース部分をとりあえず書いてみました。
{-# LANGUAGE OverloadedStrings #-} module Bencode where import Control.Monad import Control.Applicative import Data.Attoparsec.ByteString (Parser) import qualified Data.Attoparsec.ByteString.Char8 as B import Data.ByteString data BValue = String ByteString | Number Integer | List [BValue] | Dictionary [(ByteString, BValue)] deriving (Show) string :: Parser BValue string = do n <- B.decimal void $ B.char ':' String <$> B.take n number :: Parser BValue number = Number <$> (B.char 'i' *> B.signed B.decimal <* B.char 'e') list :: Parser BValue list = List <$> (B.char 'l' *> B.many' value <* B.char 'e') dictionary :: Parser BValue dictionary = do void $ B.char 'd' pairs <- B.many' ((,) <$> string <*> value) void $ B.char 'e' return $ Dictionary $ fixPair <$> pairs where fixPair (String s, v) = (s, v) value :: Parser BValue value = string <|> number <|> list <|> dictionary
実行してみます。
ghci> :set -XOverloadedStrings ghci> B.parseOnly value "d8:announce42:http://tracker.archlinux.org:6969/announce13:creation datei1438414567e4:infod6:lengthi688914432e4:name29:archlinux-2015.08.01-dual.iso12:piece lengthi524288eee" Right (Dictionary [("announce",String "http://tracker.archlinux.org:6969/announce"),("creation date",Number 1438414567),("info",Dictionary [("length",Number 688914432),("name",String "archlinux-2015.08.01-dual.iso"),("piece length",Number 524288)])])
Attoparsecにも少しずつ慣れてきた気もします。
とりあえずここまで。