【发布时间】:2026-02-02 10:10:01
【问题描述】:
我正在编写一个基于 Monads 的解释 (https://www.youtube.com/watch?v=ZhuHCtR3xq8) 组成函数 f 和 g 的 Monad。解释停在一个关键部分:要组合一个函数(比如 f)a -> ma 和另一个(比如 g)a -> ma,你需要一种将 ma 转换为 a 的方法,以便从 monad 中取出东西容器(否则你怎么能将 f 的输出输入到 g 中??),这没有得到解决。
假设我们有 f 和 g 映射一个 Integer 并返回一个 Maybe:
f :: Int -> Maybe Int
f = \x -> (Just x)
g :: Int -> Maybe Int
g = \x -> (Just x)
我想制作一个允许我组合 f 和 g 的 Monad,以便可以评估 (g o f)(x)(意思是 f(g(x)))。为此,我们需要一种将Maybe Int(f 的输出)转换为Int 的方法,以便将其发送到g。当Maybe 容器中有值时,我们只需提取该值。当 g 的输出为 Nothing 时,我们可以考虑值 0(我知道 g 的输出不能是上述 g 的 Nothing,但假设另一个 f 可以)。
这是我尝试定义执行此操作的 Monad MyMonad 的失败尝试:
f :: Int -> Maybe Int
f = \x -> (Just x)
g :: Int -> Maybe Int
g = \x -> (Just x)
data MyMonad a = Maybe a
instance Monad MyMonad where
return x = MyMonad x
Just x >>= (\x -> MyMonad (Just x))
Nothing >>= (\x -> MyMonad (Just 0))
有人可以澄清这里有什么问题吗?从教程中很难知道在函数内部进行模式匹配的正确方法是什么(在这里处理 Just vs. Nothing 的情况)并梳理实例化 Monad 的所有不同语法。这个例子没有帮助 (https://wiki.haskell.org/All_About_Monads#Maybe_a_monad):在引入 bind >>= 之后,sheep 例子甚至没有使用它,而是使用了一个组合器。
【问题讨论】:
-
为了成为
Monad,类型需要是像data MyMonad a = Maybe a这样的类型构造函数。目前,你的类型有 kind*,所以它不能变成一个 monad。 -
@4castle: 谢谢修复,但我的语法有一些更根本的问题,我不确定是什么
-
comb在您的第二个链接中是绑定。 -
您尚未将
Just或Nothing定义为MyMonad的数据构造函数。此外,您在>>=的定义中缺少=符号和函数变量。您不能对函数进行模式匹配。 -
@4castle:你能说更多关于
>>=在这种情况下的使用吗?为什么我需要等号?我不能在理论上将我所有的函数定义为 lamdas 并且从不使用等号吗?
标签: haskell functional-programming monads