Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List Haskell列表单子状态依赖_List_Haskell_State_Monads - Fatal编程技术网

List Haskell列表单子状态依赖

List Haskell列表单子状态依赖,list,haskell,state,monads,List,Haskell,State,Monads,我必须用Haskell写一个程序来解决一些不确定的问题。 我想我对单子的理解是75%,所以这是一个不经意的选择,但是 (我的问题是用船和水填充n x m板,我得到了行数和列数的总和,船的每个部分都有它的价值,现在它并不重要) 我想尽可能早地进行保护,使算法有效。问题是,船舶插入的可能性取决于我所得到的/我在previus moves中插入的内容(我们称之为board state,我不知道如何通过它,因为我无法单独从board生成新的状态) 我的算法是: 1.初始化第一块板 2.生成第一行,尝试应

我必须用Haskell写一个程序来解决一些不确定的问题。 我想我对单子的理解是75%,所以这是一个不经意的选择,但是

(我的问题是用船和水填充n x m板,我得到了行数和列数的总和,船的每个部分都有它的价值,现在它并不重要)

我想尽可能早地进行保护,使算法有效。问题是,船舶插入的可能性取决于我所得到的/我在previus moves中插入的内容(我们称之为board state,我不知道如何通过它,因为我无法单独从board生成新的状态)

我的算法是: 1.初始化第一块板 2.生成第一行,尝试应用每个可能的插入(我可以垂直插入绵羊,所以我需要记住在较低的行中插入绵羊的其他部分) 3.解决较小电路板的问题(在生成每2行后,我检查ofc是否一切正常)

但我不知道如何传递新状态,因为据我所知,状态单子仅从旧状态生成新状态,这对我来说是不可能的,我想在对值进行操作时生成新状态)


我为我对Haskell的憎恨感到抱歉,但在用命令式语言编程几年后,我被迫与那些单子们斗争,去做一些我几乎可以立即用其他语言编写的事情,这让我很生气。(Haskell中的其他东西对我来说很好,其中一些实际上相当不错)。

StateT
与列表monad结合起来,以获得您想要的行为

下面是一个使用列表单子的非确定性的简单示例,同时仍保留以前所做选择的历史记录:

import Control.Monad
import Control.Monad.Trans.Class
import Control.Monad.Trans.State

fill :: StateT [Int] [] [Int]
fill = do
    history <- get
    if (length history == 3)
        then return history
        else do
            choice  <- lift [0, 1, 2]
            guard (choice `notElem` history)
            put (choice:history)
            fill

它返回所有可能解决方案的列表。在这种情况下,这恰好是我们本可以填写董事会的所有排列的列表。

您不必一元一次地写这篇文章。您完全有能力使用良好的旧递归和映射来实现这一点。(列表monad只是
mapcont
你知道)是的,我知道绑定列表monad是如何工作的。罗列单子为我做了很多事情,比如守卫。经过一段时间的思考,离开单子是个不错的主意,有一个简单的单子解决方案。请给我一点时间写下来。嗯,恐怕StateT对我来说太多了,我不太确定它是否能解决我的问题。因为我有船,我试着插入一艘船(船和水)水平插入很容易做垂直插入我必须插入船的第一个元素,然后以某种方式将信息传递到下一行/船的其余部分,我需要插入其余部分。我需要传递我开始建造飞船的信息。插入ship后,我需要更改列和行的总和。我需要更改要插入的船舶数量……换句话说,我必须在船上状态和一些额外的行状态下操作,当生成行时,我有一个新状态。使用concatMap sems操作TOULES[(董事会、州)]列表非常容易,并且使我摆脱了单子(除了IO之外,其他都可以,但我认为我可以处理它)。考虑到我总是需要一个状态来做某件事,而我在做某件事并返回它时生成状态。哦,我误解了你的问题!在这种情况下,您根本不想使用列表monad。事实上,您可能也不想使用state。为什么不使用像
repa
这样的矩阵库呢?这样,您就不必存储列表列表
repa
是一个Haskell矩阵库,可用于存储和修改多维数组。返回类型必须是列表列表列表,因此我需要转换我的答案。不管怎样,我必须使用列表单子或者其他类似的东西。数组可以是电路板的一种表示形式,但这并不能改变我的问题是不确定的这一事实,所以我需要使用List Monad(或List with ConcatMap)。board的表示只简化了表示。@user2184057我想说的是,您的实际类型应该类似于
StateT board[]board
,其中
board
是一个矩阵/数组,而不是列表列表。这样,您仍然可以使用非决定论来探索放置船舶的多种方法,但您仍然可以使用矩阵来表示董事会。
>>> evalStateT fill []
[[2,1,0],[1,2,0],[2,0,1],[0,2,1],[1,0,2],[0,1,2]]