gpt4 book ai didi

haskell - 如何在 Haskell 中使用 Monad 类的多个构造函数参数上映射函数?

转载 作者:行者123 更新时间:2023-12-04 23:35:19 25 4
gpt4 key购买 nike

我偶然发现的问题与 >>= 应用程序的示例类型有关:

data ThreeArgs a = ThreeArgs a a a deriving (Show,Eq)

instance Functor ThreeArgs where
fmap f (ThreeArgs a b c) = ThreeArgs (f a) (f b) (f c)

instance Applicative ThreeArgs where
pure x = ThreeArgs x x x
(ThreeArgs a b c) <*> (ThreeArgs p s q) = ThreeArgs (a p) (b s) (c q)

我会声明一个 Monad 实例如下:

instance Monad ThreeArgs where
return x = ThreeArgs x x x
(ThreeArgs a b c) >>= f = f ... -- a code I need to complete

是的,看起来好像 f 将应用于所有三个 ThreeArgs 构造函数参数。如果我完成最后一行

(ThreeArgs a b c) >>= f = f a

那么编译器没有任何提示,而结果是:

*module1> let x = do { x <- ThreeArgs 1 2 3; y <- ThreeArgs 4 6 7; return $ x + y }
*module1> x
ThreeArgs 5 5 5

这意味着求和会产生具有相同参数值的上下文,尽管正确的输出应该是 ThreeArgs 5 8 10。一旦我编辑到

(ThreeArgs a b c) >>= f = (f a) (f b) (f c)

编译器警报:

 Couldn't match expected type `ThreeArgs b
-> ThreeArgs b -> ThreeArgs b -> ThreeArgs b'
with actual type `ThreeArgs b'

所以,我看到一个严重的错误引导了我的理解,但我仍然很难理解 Haskell 中的单子(monad)类和其他类似的东西。大概,我想在这里使用递归还是其他什么?

最佳答案

ThreeArgs((->) Ordering) 同构。证人:

to :: ThreeArgs a -> Ordering -> a
to (ThreeArgs x _ _) LT = x
to (ThreeArgs _ y _) EQ = y
to (ThreeArgs _ _ z) GT = z

from :: (Ordering -> a) -> ThreeArgs a
from f = ThreeArgs (f LT) (f EQ) (f GT)

您的 FunctorApplicative 实例与 ((->) r) 实例的工作方式相匹配,因此我们可以使其匹配怎么样its Monad one也有效,我们完成了。

instance Monad ThreeArgs where
ThreeArgs x y z >>= f = ThreeArgs x' y' z' where
ThreeArgs x' _ _ = f x
ThreeArgs _ y' _ = f y
ThreeArgs _ _ z' = f z

顺便说一句,ThreeArgs 等数据结构的总称是“可表示仿函数”,如果您想了解更多相关信息。

关于haskell - 如何在 Haskell 中使用 Monad 类的多个构造函数参数上映射函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59603170/

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