考虑一下,假设你有一组状态(Nel代表非空列表,为了缩短,以下同),并且你想使用一些函数f和g将这些状态合并为一个状态,其中f用于左部分,g用于右部分。因此,你想要类似这样的东西:
换句话说,您提供所有可能的移动,它模拟所有可能的状态。您可以将其视为一种决策树,在每个步骤上分支。 因此,我定义了如何处理一个咒语。
问题是,我无法通过简单遍历来实现它:
由于在遍历过程中,Nel并没有被添加到彼此之后,而是被丢弃了。 这就是我想出这个解决方法的原因:
那段代码实际上是有效的,但我感觉有一种方法可以遍历它,而不需要额外的foldState。
在概念层面上,还有哪些其他的功能性方法可以进行这样的模拟呢?我可以简单地编写函数式代码,而不使用高级概念,但这个练习的目的正是为了学习高级内容。 (也许这正是Writer Monad或Comonad的工作?)
此外,如果stackoverflow不是这样的问题的最佳场所,请指出应该在哪里提出这样的问题?
def foldStatesG[S, A](in: NonEmptyList[State[S, A]])(f: (A, A) => A)(g: (S, S) => S): State[S, A] = {
in.foldLeft1((s1, s2) => State(e => {
val ss1 = s1(e)
val ss2 = s2(e)
g(ss1._1, ss2._1) -> f(ss1._2, ss2._2)
}))
}
我相信自己正在发明自行车,而这样的事情已经存在了,可能以一种更普遍的方式存在。但是,浏览scalaz时,我没有找到或认识到它。对这个话题的任何帮助表示感激。
第二个问题描述了我如何遇到这样的问题。我想做一个小模拟,当你有一个敌人(考虑它只是一个Double),和所有可能打击他的法术Nel [Spell]。所以基本上我想生成所有可能的序列。例如,如果Nel [Spell] =($,#),那么给定一个敌人E,进展将如下:
E -> (), then Nel(E -> $, E -> #), then Nel(E -> $$, E -> ##, E -> $#, E-> #$) etc.. (pseudo code)
不需要详细解释,我需要类似这样的东西:
def combineS(variations: NonEmptyList[Spell]): State[NonEmptyList[(Enemy, List[Spell])], Boolean]
换句话说,您提供所有可能的移动,它模拟所有可能的状态。您可以将其视为一种决策树,在每个步骤上分支。 因此,我定义了如何处理一个咒语。
def combineS1(spell: Spell): State[(NonEmptyList[(Enemy, List[Spell])]), Boolean]
// some logic
问题是,我无法通过简单遍历来实现它:
def combineS(variations: NonEmptyList[Spell]): State[NonEmptyList[(Enemy, List[Spell])], Boolean] = {
val x = variations traverse combine1 // State[Nel[..], Nel[Boolean]
x map { _.suml1(conjunction)}
}
由于在遍历过程中,Nel并没有被添加到彼此之后,而是被丢弃了。 这就是我想出这个解决方法的原因:
def combineS(variations: NonEmptyList[Spell]): State[NonEmptyList[(Enemy, List[Spell])], AllDead] = {
val x: NonEmptyList[State[NonEmptyList[(Enemy, List[Spell])], Boolean]] = variations map combineS
foldStates(x)(_ && _)(append)
}
那段代码实际上是有效的,但我感觉有一种方法可以遍历它,而不需要额外的foldState。
在概念层面上,还有哪些其他的功能性方法可以进行这样的模拟呢?我可以简单地编写函数式代码,而不使用高级概念,但这个练习的目的正是为了学习高级内容。 (也许这正是Writer Monad或Comonad的工作?)
此外,如果stackoverflow不是这样的问题的最佳场所,请指出应该在哪里提出这样的问题?