Я пишу небольшую библиотеку для взаимодействия с несколькими внешними API. Один набор функций построит действительный запрос для yahoo api и проанализирует результат на тип данных. Другой набор функций будет искать текущее местоположение пользователей на основе 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 и работать вместе, не прибегая к явному шаблону, чтобы «выйти» из Maybe монады?
Кстати, почему это анти-шаблон? – Yuuri
@Yuuri, потому что похоже, что вы всегда получите результат или «ничего», но вы можете получить, скажем, исключение таймаута в сети. – dfeuer
Я не понимаю, почему вы думаете, что это выглядит как «всегда результат« Ничего ». Большинство Haskellers должны быть достаточно знакомы с трансформаторами монады, чтобы знать, как они работают «наизнанку». – leftaroundabout