Haskell中的块不符合预期

时间:2017-07-10 00:09:04

标签: haskell monads

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

似乎有些必要的习惯必须在...... ...

此代码的重点是向filterAfilterBoutput添加值,只要n不是相应过滤器列表的一部分(对于这个函数是filterA)。接受的输入被添加到两个过滤器,即使这里没有显示B功能(看起来相似)。

我显然误解了do的工作方式,因此在此代码中运行do块的结果会返回如下内容:

*Main> funA 4 [14,14,14,14]

我不明白添加到do块中的单独列表是如何混淆的。如何在相同功能下执行多个操作而不会相互干扰?

要添加,如果我删除其中一个filterA ++ [(3 ...行,结果将变为[14,14]并删除两者都会得到所需的结果[14],当然减去连接值{{1} }或filterA。但是,让它们两者产生四次重复。

TL:DR如何在filterB块内执行多​​个单独的操作?是否有可能在不深入monad的情况下理解?我错过了一个更简单的解决方案吗?

1 个答案:

答案 0 :(得分:2)

附加列表不是动作。 filterA ++ [3 * n + 2]不是一个动作,而是一个表达。它评估列表。

您可能想要使用IO monad。但是您定义的函数的返回类型是List而不是IO。在你的定义中,do块表示列表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)