Standard way to unite states in scalaz

Keep in mind that you have Nel states (Nel means NonEmptyList to make things shorter) and you want to combine states with one state using some function f for the left side of the state and g for the right side 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 a bicycle, and such a thing already exists, perhaps in a more general way. But, looking through the crag, I could not find or recognize him. I would be grateful for any help on this topic.


The second question describes how I came to such a problem. I wanted to do a little simulation when you have an Enemy (just consider him Double) and all possible spells that can hit him Nel [Spell] . So basically I want to generate all possible sequences. For example, if Nel [Spell] = ($, #), then given enemy E, the progression will look like

E -> (), then Nel(E -> $, E -> #), then Nel(E -> $$, E -> ##, E -> $#, E-> #$) etc.. (pseudo code)

Without going 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 simulate all possible states. You can consider it as a kind of decision tree that departs at every step. Therefore, I determined how to act with one spell.

def combineS1(spell: Spell): State[(NonEmptyList[(Enemy, List[Spell])]), Boolean]
    // some logic

The problem is that I cannot implement it with a simple move:

def combineS(variations: NonEmptyList[Spell]): State[NonEmptyList[(Enemy, List[Spell])], Boolean] = {
    val x = variations traverse combine1 // State[Nel[..], Nel[Boolean]
    x map { _.suml1(conjunction)}
}   

, . :

  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.

( , ). , , , . ( , ?)

, stackoverflow , , , ?

+4
1

, , , Scalaz Biapplicative, :

def foldStatesG[S, A](states: NonEmptyList[State[S, A]], s: (S, S) ⇒ S, a: (A, A) ⇒ A): State[S, A] =
  states.foldLeft1(IndexedStateT.indexedStateTBiapplicative[Id, S].bilift2(s, a))

, - (n.b. , - ):

trait Biapplicative[F[_, _]] extends Bifunctor[F] {
  def bipure[A, B](a: ⇒ A, b: ⇒ B): F[A, B]
  def biapply[A, B, C, D](fab: ⇒ F[A, B])(f: ⇒ F[A ⇒ C, B ⇒ D]): F[C, D]
  def bilift2[A, B, C, D, E, G](fab: (A, B) ⇒ C, fde: (D, E) ⇒ G): (F[A, D], F[B, E]) ⇒ F[C, G] =
    (fad: F[A, D], fbe: F[B, E]) ⇒
      biapply(fbe)(bimap[A, D, B ⇒ C, E ⇒ G](fad)(fab.curried, fde.curried))
}

object Biapplicative {
  implicit def indexedStateTBiapplicative[F[_], S1](implicit F: Applicative[F]) =
    new Biapplicative[IndexedStateT[F, S1, ?, ?]] {
      def bipure[A, B](a: ⇒ A, b: ⇒ B) =
        StateT.constantIndexedStateT(b)(a)
      def biapply[A, B, C, D]
          (fab: ⇒ IndexedStateT[F, S1, A, B])
          (f: ⇒ IndexedStateT[F, S1, A ⇒ C, B ⇒ D]) =
        new IndexedStateT[F, S1, C, D] {
          def apply(initial: S1): F[(C, D)] =
            F.ap(fab(initial))(F.map(f(initial)) {
              case (a2c, b2d) ⇒ Bifunctor[Tuple2].bimap(_)(a2c, b2d)
            })
        }
    }
}
+2

All Articles