gpt4 book ai didi

haskell - 正确使用 do 表示法

转载 作者:行者123 更新时间:2023-12-02 02:50:16 33 4
gpt4 key购买 nike

我正在尝试理解 Monad,我有以下代码

f a b c d =
do one <- a + b
two <- c * d
three <- one + two
return three

以上编译

但是当我得到一个错误

*主> f 1 2 3 4

:1:1:
(Num (a0 -> t0), Monad ((->) a0), Monad ((->) t0)) 没有实例
因使用“f”而产生
可能的修复:
添加实例声明
(Num (a0 -> t0), Monad ((->) a0), Monad ((->) t0))
在表达式中:f 1 2 3 4
在“it”的等式中:it = f 1 2 3 4

:1:9:
(Num (a0 -> a0 -> t0)) 没有实例
源自文字“4”
可能的修复:
为 (Num (a0 -> a0 -> t0)) 添加实例声明
在`f'的第四个参数中,即`4'
在表达式中:f 1 2 3 4
在“it”的等式中:it = f 1 2 3 4

如果我知道为什么上面的代码不起作用,我想我会更接近理解 Monad f 1 2 3 4

最佳答案

问题是您将包装的一元值与纯值混淆了。

首先要知道的是 do 表示法是常规函数调用的语法糖( >>=>> )。因此,这将有助于查看您的代码也脱糖。

让我们尝试一些更简单的东西

 f a b =
do one <- a + b
return one

这与您的代码有相同的问题,但更简单。为了理解为什么它不起作用,我们问:这实际上意味着什么?好吧,我们可以重写 <-使用 >>= 的符号
 f a b = (a + b) >>= \x -> return x

(这不是最简单的表示,但说明了这一点)

如果您在 GHCi 中测试以下内容
 >> :t (>>=)
Monad m => m a -> (a -> m b) -> m b

即函数 >>=接受: m 类型的参数的 a以及来自 a 的函数至 mb并返回 mb .

在这段代码中呢?
(a + b)

将是一个数字。
另一半怎么样
 \x -> return x

采用 a 类型的对象并返回 m a 类型的对象对于任何 a
所以,你需要有一个数字,这也是某种单子(monad)。你能想到这样的事情吗?目前尚不清楚这将是什么,这是怀疑这应该进行类型检查的一个原因。

了解 monad 的一种好方法是看一些具体的例子。
Maybe monad 表示可能失败的计算
 instance Monad Maybe where
return = Just
(>>=) (Just a) f = f a
(>>=) Nothing _ = Nothing

这让你可以用类似的语气说话
 f args = do x <- functionThatMightFail args
y <- anotherfunctionThatMightFail x
return y

或更简单的相同代码
f args = do x <- functionThatMightFail args
anotherfunctionThatMightFail x

也许
f args = functionThatMightFail args >>= anotherfunctionThatMightFail

另一方面, List monad 捕捉到对列表的每个元素执行相同功能,然后将结果连接在一起的想法。简单的例子比比皆是:
f = do x <- [1,2,3,4]
[1..x]

如果您了解这些,请使用 State单子(monad)。它可以帮助您了解“monad 是计算模型”这一更一般的概念。然后我会检查 Parsec,当然还有 IO

关于haskell - 正确使用 do 表示法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7962890/

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