Haskell 中的代码块未按预期运行
Do blocks in Haskell not behaving as expected
filterA = [3]
filterB = [2]
output = []
funA n =
if not (elem (n) filterA)
then do
filterA ++ [(3 * n + 2) ]
filterB ++ [(3 * n + 2) ]
output ++ [(3 * n + 2)]
else output
看来必须养成一些必要的习惯...
这段代码的重点是向filterA
、filterB
和output
添加一个值,只要n
不是相应过滤器列表的一部分(对于此函数,它是 filterA
)。已接受的输入被添加到两个过滤器,即使 B 函数(看起来相似)未在此处显示。
我显然误解了 do
的工作方式,因此在这段代码中运行 do
块会返回如下内容:
*Main> funA 4
[14,14,14,14]
我不明白在 do
块中添加到单独的列表是如何混淆的。如何在同一个函数下执行多个操作而不相互干扰?
此外,如果我删除 filterA ++ [(3 ...
行之一,结果变为 [14,14]
并且删除两行会得到所需的结果 [14]
,当然减去将值连接到 filterA
或 filterB
。但是关于同时拥有它们的一些东西会产生四个重复。
TL:DR 如何在 do
块内执行多个单独的操作?不深入monad是否可以理解?是否缺少更简单的解决方案?
追加列表不是一个动作。 filterA ++ [3 * n + 2]
不是一个动作,而是一个表达式。它计算为列表。
您可能想要使用 IO monad。但是你定义的函数的return类型是List,不是IO。在您的定义中,do block 表示列表 monad 而不是 IO monad。
而在Haskell中,一旦定义的值就不能更改。
您可能需要执行以下操作。
funA n = if not (elem n filterA)
then let
filterA' = filterA ++ [3 * n + 2]
filterB' = filterB ++ [3 * n + 2]
output' = output ++ [3 * n + 2] in
(filterA', filterB', output')
else (filterA, filterB, output)
filterA = [3]
filterB = [2]
output = []
funA n =
if not (elem (n) filterA)
then do
filterA ++ [(3 * n + 2) ]
filterB ++ [(3 * n + 2) ]
output ++ [(3 * n + 2)]
else output
看来必须养成一些必要的习惯...
这段代码的重点是向filterA
、filterB
和output
添加一个值,只要n
不是相应过滤器列表的一部分(对于此函数,它是 filterA
)。已接受的输入被添加到两个过滤器,即使 B 函数(看起来相似)未在此处显示。
我显然误解了 do
的工作方式,因此在这段代码中运行 do
块会返回如下内容:
*Main> funA 4
[14,14,14,14]
我不明白在 do
块中添加到单独的列表是如何混淆的。如何在同一个函数下执行多个操作而不相互干扰?
此外,如果我删除 filterA ++ [(3 ...
行之一,结果变为 [14,14]
并且删除两行会得到所需的结果 [14]
,当然减去将值连接到 filterA
或 filterB
。但是关于同时拥有它们的一些东西会产生四个重复。
TL:DR 如何在 do
块内执行多个单独的操作?不深入monad是否可以理解?是否缺少更简单的解决方案?
追加列表不是一个动作。 filterA ++ [3 * n + 2]
不是一个动作,而是一个表达式。它计算为列表。
您可能想要使用 IO monad。但是你定义的函数的return类型是List,不是IO。在您的定义中,do block 表示列表 monad 而不是 IO monad。
而在Haskell中,一旦定义的值就不能更改。
您可能需要执行以下操作。
funA n = if not (elem n filterA)
then let
filterA' = filterA ++ [3 * n + 2]
filterB' = filterB ++ [3 * n + 2]
output' = output ++ [3 * n + 2] in
(filterA', filterB', output')
else (filterA, filterB, output)