Skip to content

Instantly share code, notes, and snippets.

@cohama
Last active August 29, 2015 14:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cohama/adb37857a8434f0c014f to your computer and use it in GitHub Desktop.
Save cohama/adb37857a8434f0c014f to your computer and use it in GitHub Desktop.

Twitter クライアントを作る

準備

git clone git://github.com/cohama/twittermonad
cd twittermonad
cabal sandbox init
cabal install --only-dependencies
cabal configure
cabal build

動かしてみる

dist/build/twittermonad/twittermonad tl
# 初回は OAuth の認証が走るはず

dist/build/twittermonad/twittermonad tw "つぶやいてみる"

Twitter モナド

副作用をモナドで表現する

getStrLn :: IO String

putStrLn :: String -> IO ()

IO はいろいろできすぎてしまうので機能を限定したモナドを作る (DSL)

homeTimeLine :: Twitter [Tweet]

tweet :: String -> Twitter ()

fav :: TweetID -> Twitter ()

reply :: TweetID -> String -> Twitter ()

Twitter モナドに求める能力

  • HTTP通信やファイル読み書き、その他もろもろ副作用っぽいこと => IO
  • 設定情報を読む => Reader
  • 失敗するかもしれない => Either

これらを Monad Transformer で積み上げる

newtype Twitter a = Twitter { unTwitter :: ExceptT String (ReaderT Conf IO) a }
                    deriving (Functor, Applicative, Monad, MonadIO, MonadReader Conf)

runTwitter :: Conf -> Twitter a -> IO (Either String a)
runTwitter c t = flip runReaderT c . runExceptT . unTwitter $ t

OAuth

OAuth v1.1 です。 nonce や timestamp のせいで IO を使わざるを得ない

makeAuthorization :: String             -- httpMethod (GET|POST)
                  -> String             -- URL
                  -> [(String, Text)]   -- parameters
                  -> BS.ByteString      -- oauth consumer key
                  -> BS.ByteString      -- oauth consumer secret
                  -> BS.ByteString      -- oauth token
                  -> BS.ByteString      -- oauth token secret
                  -> IO BS.ByteString

HTTP 通信

wreq というライブラリを利用。 レスポンスから Lens 経由で値を取り出せる

wreq tutorial

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment