我们有以下功能来构建一棵树。 它是一棵树,它有一个Node和你想要的多个子树。
INSERT INTO #Results ( . . . )
SELECT . . .
FROM WarehouseMgmt.DimTime DT LEFT JOIN
WarehouseMgmt.FactPaymentAgr Aggr
ON DT.Id = Aggr.TimeId AND [PlayerId] = @PlayerID
WHERE (CalendarWeekId BETWEEN @CurrentWeek7 AND @CurrentWeek)
GROUP BY PlayerId, CalendarWeekID
现在的问题是找到一个递归的基本情况。 我们有一个名为identifyWinner的函数,它可以完成它所说的内容。
这个想法是,使用这个函数来确定某人是否赢了,并在发生时停止制作子树。但这看起来像这样:
generateGameTree g p = Node (g,p) [ ((fst x),generateGameTree (snd x) (nextPlayer p)) | x <- (findPossibleMoves p g) ]
我们无法弄清楚如何实际做任何事情。 有没有办法在Haskell中实现这一点?
提前致谢!
答案 0 :(得分:3)
首先,它是 un-Haskell 来说Haskell做了一些事情,这是声明性编程和懒惰编程的全部要点。您描述输出。实际生成方式取决于编译器。
要回答您的问题,您可以稍微更改一下您的功能,以便它允许Maybe
:
generateGameTree g p =
| identifyWinner g p == Nothing = Just $ Node (g,p) $ filter (isJust . snd) [ ((fst x),generateGameTree (snd x) (nextPlayer p)) | x <- (findPossibleMoves p g) ]
| otherwise = Nothing
filter
将过滤掉树中的Nothing
。
另一个(或多或少等价的)解决方案是生成节点列表,列表为空或单例:
generateGameTree g p =
| identifyWinner g p == Nothing = [Node (g,p) $ concat [ ((fst x),generateGameTree (snd x) (nextPlayer p)) | x <- (findPossibleMoves p g) ] ]
| otherwise = []
答案 1 :(得分:1)
如果你有一个功能
nextPositions :: Game -> [Game]
给出了在给定位置采取所有可能移动可能产生的所有位置,然后游戏树是来自Control.Comonad.Cofree
的Cofree [] Game
type GameTree = Cofree [] Game
可以使用
生成generateGameTree :: Game -> GameTree
generateGameTree = coiter nextPositions
如果获胜的位置没有下一个位置,那么该代将自动停在获胜位置。如果需要,您可以将其转换为更常见的Data.Tree
表示。
答案 2 :(得分:0)
如果已经有胜利者,这意味着游戏已经结束并且没有更多动作,那么结果应该是什么,游戏的当前状态以及没有孩子的列表,所以:
makeGameTree g p =
| identifyWinner g p == Nothing =
Node (g,p) [ (fst x, makeGameTree (snd x) (nextPlayer p))
| x <- (findPossibleMoves p g) ]
| otherwise = Node (g,p) []