Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell在返回maybes的函数中避免双重包装的maybes_Haskell_Monads_Functor_Maybe - Fatal编程技术网

Haskell在返回maybes的函数中避免双重包装的maybes

Haskell在返回maybes的函数中避免双重包装的maybes,haskell,monads,functor,maybe,Haskell,Monads,Functor,Maybe,我可以看到,这里有很多关于Maybe类型和构图的问题,但是我很困惑,如果我很诚实的话,读这些会让我头疼 我的情况如下: 举例来说,我有一个函数: addm a b = Just (a + b) 如何使用addm函数创建函数add::Maybe Int->Maybe Int->Maybe Int,而不使用模式匹配来展开Maybes 我试过类似的东西 add x y = (addm <$> x) <*> y 这就成功了。不过,我仍然对原始问题的答案感到好奇。在顶部粘贴一个

我可以看到,这里有很多关于Maybe类型和构图的问题,但是我很困惑,如果我很诚实的话,读这些会让我头疼

我的情况如下:

举例来说,我有一个函数:

addm a b = Just (a + b)
如何使用
addm
函数创建函数
add::Maybe Int->Maybe Int->Maybe Int
,而不使用模式匹配来展开
Maybe
s

我试过类似的东西

add x y = (addm <$> x) <*> y

这就成功了。不过,我仍然对原始问题的答案感到好奇。

在顶部粘贴一个
join

Control.Monad.join :: Monad m => m (m a) -> m a -- combine two ms into one, this is why, as the meme goes, monads are monoids in the category of endofunctors

add x y = join $ addm <$> x <*> y
Control.Monad.join::Monad m=>m(ma)->ma--将两个ms合并为一个,这就是为什么,正如模因所说,Monad是内函子范畴中的幺半群
add x y=加入$addm x y

我想指出,像这样编写
addm
(实际上,任何总是返回
的函数都是不自然的。实际上,您只需编写
addxy=(+)xy
add=liftA2(+)
,但在处理实际有趣的一元代码时,在应用程序样式的表达式顶部抛出
join
的一般模式非常有用。

在顶部粘贴一个
join

Control.Monad.join :: Monad m => m (m a) -> m a -- combine two ms into one, this is why, as the meme goes, monads are monoids in the category of endofunctors

add x y = join $ addm <$> x <*> y
Control.Monad.join::Monad m=>m(ma)->ma--将两个ms合并为一个,这就是为什么,正如模因所说,Monad是内函子范畴中的幺半群
add x y=加入$addm x y

我想指出,像这样编写
addm
(实际上,任何总是返回
的函数都是不自然的。实际上,您只需编写
addxy=(+)xy
add=liftA2(+)
,但在处理真正有趣的一元代码时,将
join
置于应用程序样式的表达式之上的一般模式非常有用。所有这些都涉及到一个事实,
可能是一个单子

也许最容易理解的方法是使用函数,对于任何Monad,它都会删除最外层的嵌套。这里有类型
Maybe(maybea a)->maybea a
,这正是您所寻找的,与标准应用程序运算符结合使用:

add ma mb = join $ addm <$> ma <*> mb
或者您可以显式地使用“bind”(
>=
)操作符,这是desugars上面的
块要做的事情(但我发现这比其他两个选项更不明确,更难理解):


写这篇文章有很多方法。所有这些都涉及到一个事实,
可能是一个单子

也许最容易理解的方法是使用函数,对于任何Monad,它都会删除最外层的嵌套。这里有类型
Maybe(maybea a)->maybea a
,这正是您所寻找的,与标准应用程序运算符结合使用:

add ma mb = join $ addm <$> ma <*> mb
或者您可以显式地使用“bind”(
>=
)操作符,这是desugars上面的
块要做的事情(但我发现这比其他两个选项更不明确,更难理解):

使用原力类型,卢克

您的
addm
具有类型
Int->Int->Maybe Int
。你的目标是用一种方式来包装它,它会给你一个
Maybe Int->Maybe Int->Maybe Int->Maybe Int
。为此,我们需要一个类型为
(Int->Int->Maybe Int)->Maybe Int->Maybe Int->Maybe Int
的函数。如果我们这样做,尽管在
base
中没有结果,但在第三方库中有一些结果。和是等价的,两者都能做你想做的事。如果您不想为此引入新的依赖项,请检查这些依赖项的来源以了解它们是如何实现的:

bind2 :: Monad m => (a -> b -> m c) -> m a -> m b -> m c
bind2 f x y = liftA2 (,) x y >>= uncurry f
(我在这里稍微修改了
liftJoin2
,只直接使用
base
方法,而不是
utility ht
的重命名包装。)

您的
addm
具有类型
Int->Int->Maybe Int
。你的目标是用一种方式来包装它,它会给你一个
Maybe Int->Maybe Int->Maybe Int->Maybe Int
。为此,我们需要一个类型为
(Int->Int->Maybe Int)->Maybe Int->Maybe Int->Maybe Int
的函数。如果我们这样做,尽管在
base
中没有结果,但在第三方库中有一些结果。和是等价的,两者都能做你想做的事。如果您不想为此引入新的依赖项,请检查这些依赖项的来源以了解它们是如何实现的:

bind2 :: Monad m => (a -> b -> m c) -> m a -> m b -> m c
bind2 f x y = liftA2 (,) x y >>= uncurry f

(我在这里稍微修改了
liftJoin2
,只直接使用
base
方法,而不是
utility ht
重命名的包装器。)

应用程序函子不是你想要的吗?也许?我对哈斯克尔还是个新手,所以我不太明白这是怎么回事。我想如果
addm
本身没有返回一个Maybe就可以了。我和Haskell也相处得很好已经很久了,但这可能会帮助你:。这不一样,但可能会引导到正确的方向track@GrayCat我很确定您需要
Monad
实例来执行此操作,不仅仅是应用程序methods@GrayCat好资源,谢谢;但它并没有真正向我展示我在Hoogle上查找
时没有看到的任何东西。我还是很困。应用函子不是你要找的吗?也许吧?我对哈斯克尔还是个新手,所以我不太明白这是怎么回事。我想如果
addm
本身没有返回一个Maybe就可以了。我和Haskell也相处得很好已经很久了,但这可能会帮助你:。这不一样,但可能会引导到正确的方向track@GrayCat我很确定您需要
Monad
实例来执行此操作,不仅仅是应用程序methods@GrayCat好资源,谢谢;但它并没有真正向我展示任何我在Hoogle上看不到的东西
liftJoin2 :: (Monad m) => (a -> b -> m c) -> m a -> m b -> m c
liftJoin2 f ma mb =
   join (liftM2 f ma mb)