Monad Transformer Stacks in Scala

I study monad transformers in Scala, but I ran into a problem that I consider impossible so far. In my monad transformer block, I make up the League and the State Monad. However, I cannot call functions that belong to one of two monads:

import scalaz._
import Scalaz._

object Minimal {
  type Inner[A] = EitherT[Id, String, A]
  type Outer[F[+_], A] = StateT[F,Int,A]
  type Stack[A] = Outer[Inner, A]

  def foo:Stack[Int] = for {
    n <- get[Int]
  } yield {
    2 * n
  }

  def main(args: Array[String]): Unit = {
    val x = foo.eval(8)
    println(x)
  }
}

The following error message failed:

[error] Minimal.scala:10: type mismatch;
[error]  found   : scalaz.IndexedStateT[scalaz.Id.Id,Int,Int,Int]
[error]  required: Minimal.Stack[Int]
[error]     (which expands to)  scalaz.IndexedStateT[Minimal.Inner,Int,Int,Int]
[error]     n <- get[Int]

If I changed the monad transformer stack to:

type Stack[A] = State[Int,A]

The program compiles and runs without problems. Does anyone know what I'm doing wrong here?

+4
source share
2 answers

get[Int] IndexedStateT[Id, Int, Int, Int]. Stack[Int] IndexedStateT[Inner, Int, Int, Int], Inner EitherT[Id, String, A]. , .

Inner StateT Option.

type Stack[A] = StateT[Option, Int, A]

get[Int] - .

val x:Stack[Int] = get[Int]
//type mismatch; 
//  found : scalaz.State[Int,Int]
//    (which expands to) scalaz.IndexedStateT[scalaz.Id.Id,Int,Int,Int]
//  required: Minimal.Stack[Int] 
//    (which expands to) scalaz.IndexedStateT[Option,Int,Int,Int]

, lift Option:

val x:Stack[Int] = get[Int].lift[Option]

, lift State Inner, . , Inner :

type Inner[+A] = EitherT[Id, String, A]
type Stack[A] = StateT[Inner, Int, A]

val x:Stack[Int] = get[Int].lift[Inner]

, . :

type Inner[+A] = EitherT[Id, String, A]
type Outer[F[+_], A] = StateT[F, Int, A]
type Stack[A] = Outer[Inner, A]

implicit def liftToStack[A](x:Outer[Id, A]):Stack[A] = x.lift[Inner]

def foo: Stack[Int] = for {
  n <- get[Int]
} yield {
  2 * n
}
+5

EECOLOR answer ( , - ), , .

EECOLOR , MonadState ( ) . , :

import scalaz._, Scalaz._

type Inner[+A] = EitherT[Id, String, A]
type Stack[S, +A] = StateT[Inner, S, A]

def foo: Stack[Int, Int] = for {
  n <- MonadState[Stack, Int].get
} yield 2 * n

, ( ) Stack, . :

type MyState[S, +A] = StateT[Inner, S, A]
type Stack[+A] = MyState[Int, A]

.

+5

Source: https://habr.com/ru/post/1533349/


All Articles