【问题标题】:Implementation of backtracking in HaskellHaskell中回溯的实现
【发布时间】:2021-04-02 13:27:36
【问题描述】:

对 Haskell 来说是全新的,我将不胜感激。

在 Prolog 中实现谓词,利用一些减少解决方案空间的约束,使整体实现不是天真的/蛮力的,这非常容易。但是现在我必须处理 Haskell,我不知道该怎么做。

鉴于在某个时间点 P1 我会选择说 A1,而在稍后的时间点 P2 我会选择说 A1不遵守我的约束的strong>A2我怎样才能回到P1并在Haskell中做出不同的选择?

我现在学习 Haskell 2 天了,根据我的阅读,这可能是可行的,方法是在函数内部声明一个函数,或者使用我不太理解和困惑的 monad。

您能否将我链接到/显示一些简单的选择它 - 将其置于约束下 谓词,这些谓词使用回溯 - 最好没有单子 - 这样我就可以绕过它?

【问题讨论】:

  • @MichaelLitchard 这个问题更多的是关于 Haskell 中的回溯。
  • @MichaelLitchard 编辑了问题,以便更准确地反映我的需要。

标签: haskell recursion functional-programming backtracking


【解决方案1】:

当然,这是一个简单的选择一个数字,然后如果它发现该数字不是偶数,它会备份并选择另一个。

searchForEven :: [Int] -> [Int]
searchForEven ns = [n | n <- ns, even n]

这是一个与您描述的情况相匹配的示例:

假设我在某个时间点 P1 做了一个选择,说 A1,而在稍后的时间点 P2 我做了一个选择,说 A2 不遵守我的约束,我怎么能回到 P1 并做出不同的选择?

p1 = [1..10]
p2 = [2,3,5,7]
constraint a b = a^2 + b^2 == 5^2

searchForPythagoreanTriple :: [Int]
searchForPythagoreanTriple =
    [ (a1, a2)
    | a1 <- p1
    , a2 <- p2
    , constraint a1 a2
    ]

我使用了我希望是相当具有暗示性的名称来突出示例如何与您描述的场景联系起来。

不要害怕单子。看看它在 monad 语法中是如何相同的:

searchForEven ns = do
    n <- ns
    guard (even n)
    pure n

searchForPythagoreanTriple = do
    a1 <- p1
    a2 <- p2
    guard (constraint a1 a2)
    pure (a1, a2)

【讨论】:

  • 所以基本上守卫的工作方式是确保约束没有被破坏?如果我有多个约束怎么办?
  • @RookieCookie 是的,对于列表,guard False = []; guard True = [()]。如果您有多个约束,您将多次调用guard
猜你喜欢
  • 1970-01-01
  • 2021-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多