Давайте предположим, что мы имеемДвукратное БПМЖ применение
a :: IO (Maybe String)
b :: IO (Maybe String)
data Foo = Foo String String
И я хочу, чтобы получить Maybe Foo
от a
и b
.
В настоящее время я делаю это
do
a' <- a
b' <- b
Foo <$> a' <*> b'
Но я чувствую, что должен быть более простой способ,
(\x y -> Foo <$> x <*> y) <$> (Just <$> getLine) <*> (return Nothing)
ли трюк, но я не хочу, чтобы создать что уродливая лямбда там. Есть ли такой оператор, как <$>
, но с двухкратным приложением? Или есть ли способ объединить IO (Just a)
, чтобы иметь одну монаду?
Edit:
Я думаю, тип подписи:
(Monad m, Monad n) => (a -> b -> c) -> (m (n a)) -> (m (n b)) -> (m (n c))
Edit2:
Извините за не ясно, моя структура данных имеет более двух полей, это фактически структура конфигурации, имеющая ~ 15 полей.
cfg <- Conf.load [ Conf.Required cfile ]
foo1 <- (Conf.lookup cfg "foo1" :: Maybe String)
foo2 <- Conf.lookup cfg "foo2"
foo3 <- Conf.lookup cfg "foo3"
foo4, foo5, foo6...
return $ Conf <$> foo1
<*> foo2
<*> foo3
<*> foo4
...
Вы можете использовать 'liftM2 (\ аЬ -> Foo <$><*> б)' – josejuan
Вы можете использовать 'а, Ь: : MaybeT IO String'. Тогда это просто 'Foo <$> a <*> b'. –