小编Jak*_*son的帖子

什么是更好的方法来写[(-1,-1),( - 1,0),( - 1,1),(0,-1),(0,1),(1,-1), Haskell中的(1,0),(1,1)]?

我遇到了一些我需要列表的情况:

[(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)] -- no (0,0)
Run Code Online (Sandbox Code Playgroud)

请注意,列表中没有(0,0).我使用(dx,dy)元组从坐标向上,向下,向左,向右和对角搜索.

每次我写它时,我觉得应该有一个更简洁,和/或更容易阅读的方式来定义它.我对Haskell比较陌生,而且我认为在Applicative/Functor/Monad技巧的某个地方应该有一个巧妙的方法来做到这一点.

我试过了:

[(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)]
Run Code Online (Sandbox Code Playgroud)

有时最好把它写出来,但我认为这不是其中之一.一目了然(0,0)不包括在内并且你必须阅读它以注意模式.

map (\[a,b] -> (a,b)) $ delete [0,0] $ sequence $ replicate 2 [-1,0,1]
Run Code Online (Sandbox Code Playgroud)

我喜欢上面的那个,因为我把"2"放在那里,这是一个很好的明确方式来说"我们两次做同样的事情",但我不能接受前面的地图与大不安全的lambda和2个名字.

[(dx,dy) | let a = [-1,0,1], dx <- a, dy <- a, (dx,dy) /= (0, 0)]
Run Code Online (Sandbox Code Playgroud)

这个名称中包含太多名称,但完全按照设计使用列表推导.对于那些真正喜欢列表推导的人来说,可能更容易阅读,但我不喜欢所有的名字.

let x = [-1,0,1] in delete (0,0) $ (,) <$> x <*> x
Run Code Online (Sandbox Code Playgroud)

那个看起来更漂亮的imo,但我没有那个"2",我有一个名字.到目前为止,这是我的最爱,但它并不完美.

我想如果我理解如何更好地写这个,我可能会更深入地了解Functors/Monads等.我已经读了很多关于它们的内容,我听过很多像fmap/mconcat/etc这样的词,但我不知道在这种情况下要抓哪一个.

haskell list-comprehension applicative

16
推荐指数
4
解决办法
1004
查看次数

如何将列表monadic函数转换为广度优先搜索?

我刚刚解决了如何使用List monad进行非确定性计算的问题.但是我相信我的算法会受益于广度优先搜索,而不是从List monad获得的深度优先搜索.

这是一个摘录,显示了我的算法的有趣部分.它是逻辑拼图Akari的解算器.

solve :: Game -> [Game]
solve game = do
        let ruleBasedSolverResult = applyRuleBasedSolversUntilSteady game
        guard $ consistant ruleBasedSolverResult
        if solved ruleBasedSolverResult
                then return ruleBasedSolverResult
                else speculate ruleBasedSolverResult

speculate :: Game -> [Game]
speculate game = do
        coord <- coords game
        guard $ lightableUnlit game coord
        let solutions = solve $ light game coord
        if null solutions
                then solve $ exclude game coord
                else solutions
Run Code Online (Sandbox Code Playgroud)

基本上它应用一些基本的确定性规则来看看是否能解决它.如果没有,它会尝试将灯光放在不同的地方.如果光线在递归解决后使拼图不一致,则在光线所在的位置放置一个排除标记.如果在放置灯光时找到解决方案,则会将其添加到解决方案列表中.

这样做很好,但速度很慢,因为通常有一个明显的选择,哪个coord可以快速导致一个不一致的拼图,让你只用一(或两个)级别的搜索放置一个x,但如果它没有'在搜索到中途之前选择那个coord然后它会先咀嚼一堆无趣的东西.因此,广度优先搜索的想法.

我用谷歌搜索了"广泛的第一个非反感monad",我得到了一些难以理解的结果,如:

  • Control.Monad.Omega对于我需要的东西来说这似乎有点过分,因为它似乎可以防止无限分歧的决定论,但对我来说并非如此,我并不完全理解它.

  • Control.Monad.Weighted搜索Control.Monad.Omega 的文档建议在使用它作为Monad时使用它,但我认为加权对我的需求来说也有点矫枉过正.我可能只有2个权重,一个用于解决方案,一个用于没有解决方案的东西.

  • Control.Monad.Level我不相信这会对我想要的东西起作用,因为只有树的叶子有值.

  • Data.Tree我认为这可能是我想要使用的,但我不知道如何转换我的List monadic代码来使用它,虽然我觉得有一种美妙的方式. …

monads haskell breadth-first-search non-deterministic

6
推荐指数
1
解决办法
356
查看次数