私はいくつかの外部APIとやりとりするための小さなライブラリを書いています。 1つの関数セットは、yahoo APIへの有効なリクエストを作成し、その結果をデータ型に解析します。もう1つの関数セットは、IPに基づいてユーザーの現在の場所を検索し、現在の場所を表すデータ型を返します。コードが機能する間、それはタイプIO(たぶんa)のシーケンスの複数の関数に明示的にパターンマッチする必要があるようです。IO型の連鎖機能(たぶんa)
-- Yahoo API
constructQuery :: T.Text -> T.Text -> T.Text
constructQuery city state = "select astronomy, item.condition from weather.forecast" <>
" where woeid in (select woeid from geo.places(1)" <>
" where text=\"" <> city <> "," <> state <> "\")"
buildRequest :: T.Text -> IO ByteString
buildRequest yql = do
let root = "https://query.yahooapis.com/v1/public/yql"
datatable = "store://datatables.org/alltableswithkeys"
opts = defaults & param "q" .~ [yql]
& param "env" .~ [datatable]
& param "format" .~ ["json"]
r <- getWith opts root
return $ r ^. responseBody
run :: T.Text -> IO (Maybe Weather)
run yql = buildRequest yql >>= (\r -> return $ decode r :: IO (Maybe Weather))
-- IP Lookup
getLocation:: IO (Maybe IpResponse)
getLocation = do
r <- get "http://ipinfo.io/json"
let body = r ^. responseBody
return (decode body :: Maybe IpResponse)
- Combinatorの
runMyLocation:: IO (Maybe Weather)
runMyLocation = do
r <- getLocation
case r of
Just ip -> getWeather ip
_ -> return Nothing
where getWeather = (run . (uncurry constructQuery) . (city &&& region))
が、それはのgetLocationスレッドとたぶんモナドの「脱出」するマッチング明示的なパターンに頼らずに一緒に実行することは可能ですか?
ところで、なぜこれは反パターンですか? – Yuuri
@ Yuuri、あなたはいつも結果や 'Nothing'を得るように見えるので、ネットワークタイムアウト例外が出るかもしれません。 – dfeuer
「いつもNothingの結果」のように見える理由は分かりません。ほとんどのハスケラーは、モナド変圧器がどのように「内側に」働いているかを知るためには十分に精通している必要があります。 – leftaroundabout