gpt4 book ai didi

haskell - 二次fmap应用

转载 作者:行者123 更新时间:2023-12-01 12:39:25 25 4
gpt4 key购买 nike

假设我们有

a :: IO (Maybe String)
b :: IO (Maybe String)

data Foo = Foo String String

我想获得一个 Maybe Foo来自 ab .

目前,我正在做这件事

do
a' <- a
b' <- b
Foo <$> a' <*> b'

但是,我觉得应该有更简单的方法,

(\x y -> Foo <$> x <*> y) <$> (Just <$> getLine) <*> (return Nothing)

有诀窍,但我不想在那里创建那个丑陋的 lambda。有没有像<$>这样的运营商?但有双重应用?或者有什么方法可以结合 IO (Just a)有一个单子(monad)?

编辑:

我认为类型签名是:

(Monad m, Monad n) => (a -> b -> c) -> (m (n a)) -> (m (n b)) -> (m (n c)) 

编辑2:

抱歉没说清楚,我的数据结构有两个以上的字段,它实际上是一个配置结构,有 ~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
...

最佳答案

可能是最简单的解决方案:

(liftA2 . liftA2) Foo :: IO (Maybe String) -> IO (Maybe String) -> IO (Maybe Foo)

liftM2 也可以。我更喜欢最弱的可接受解决方案(并且随着 GHC 7.10 即将到来的 Applicative-Monad 父类(super class)化,这将完全没有争议)。

或者,如果 IO (Maybe a) 频繁出现,您可以使用 monad 转换器,这样您就可以使用 liftA2 提升任意数量的 monad/提升M2:

import Control.Monad.Trans.Maybe
import Control.Applicative

liftA2 Foo :: MaybeT IO String -> MaybeT IO String -> MaybeT IO Foo

关于haskell - 二次fmap应用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26404369/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com