Consider, you have the Nel of states (Nel stands for NonEmptyList, to make things shorter), and you want to combine the States to one State, using some function f, for left part of the state and g for the right part of the state.
So you want something like this:
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)
}))
}
I am sure, that I am inventing the bicycle, and such thing already exists, probably in a more general way. But, looking through scalaz I failed to find or recognize it. Would appreciate of any help on this topic.
The second question, describes how I came to such problem. I wanted to make a small simulation, when you have an Enemy (consider it's just a Double), and all possible spells which might hit him Nel[Spell]. So basically I want to generate all possible sequences. For example, if Nel[Spell] = ($, #), then given an enemy E, progression would look like
E -> (), then Nel(E -> $, E -> #), then Nel(E -> $$, E -> ##, E -> $#, E-> #$) etc.. (pseudo code)
Without going too much into details I need something like this:
def combineS(variations: NonEmptyList[Spell]): State[NonEmptyList[(Enemy, List[Spell])], Boolean]
In other words, you provide it with all possible moves, and it simulates all possible states. You can consider it as a kind of decision tree, which branches off every step. Hence I defined, how to proceed with one spell.
def combineS1(spell: Spell): State[(NonEmptyList[(Enemy, List[Spell])]), Boolean]
// some logic
The problem is, that I can not implement it via simple traverse:
def combineS(variations: NonEmptyList[Spell]): State[NonEmptyList[(Enemy, List[Spell])], Boolean] = {
val x = variations traverse combine1 // State[Nel[..], Nel[Boolean]
x map { _.suml1(conjunction)}
}
Because in traverse, the Nels are not appended to each other, but discarded. That's why I came up with this solution:
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)
}
That code is actually working, but I feel like there's a way to traverse it, without additional foldState.
What would be other functional approaches to do such simulations (in terms of concepts at least). I can write it simply functional, without using high level concepts, but the purpose of this exercise was exactly to learn advanced stuff. (May be it is exactly the job for Writer Monad? or Comonad?)
Also, if stackoverflow is not the best place for such questions, please, point out, where such questions are supposed to be asked?