3

変更できない関数は ScalazReaderを返します。

type Action[A] = Reader[Session, A]

def findAccount(s: String): Action[Account] = 
  Reader((session: Session) => Account(s))

次のようfindAccount(...)に返すことに基づいて新しい関数を作成したいReaderT[Option, Session, A]

type ActionT[A] = ReaderT[Option, Session, A]

def findAccountT(s: String): ActionT[Account] = findAccount(s).map(Option(_))

最終的にはこれをやりたいので、

def findAccBalT(accountNumber: String) = for {
  acc <- findAccountT(accountNumber)
  bal <- findBalanceT(acc)
}  yield bal

続行するにはどうすればよいですか?それは理にかなっていますか?ありがとう

完全な開示、

import scalaz._
import Scalaz._        

trait Session {
  def doSomething(): Unit
}

case class Account(number: String) extends AnyVal
case class Amount(value: Int, currency: String) 
case class DBSession() extends Session {
  override def doSomething = println("writing to db")
}

type Action[A] = Reader[Session, A]
type ActionT[A] = ReaderT[Option, Session, A]

def findAccount(s: String): Action[Account] = 
  Reader((session: Session) => Account(s))

def findBalance(account: Account): Action[Amount] = 
  Reader((session: Session) => Amount(333, "S$"))

// failed
def findAccountT(s: String): ActionT[Account] = findAccount(s).map(Option(_))

// failed
def findBalanceT(account: Account): ActionT[Amount] = findBalance(account).map(Option(_))

// failed
def findAccBalT(accountNumber: String) = for {
  acc <- findAccountT(accountNumber)
  bal <- findBalanceT(acc)
}  yield bal
4

1 に答える 1

2

簡単な答え: を使用できますmapK

Reader[A]は の型エイリアスでReaderT[Id, A]あり、ReaderTは のエイリアスですKleisliId[A]と同じAです。

KleisliScalaDoc には次のようなものがありますmapK

def mapK[N[_], C](f: (M[B]) => N[C]): Kleisli[N, A, C]

これは に移動するために使用できるものReader[Session, A]と同じであることがわかっているため:Kleisli[Id, Session, A]mapKKleisli[Option, Session, A]

import scalaz._, Scalaz._

type Session = String
type Action[A] = Reader[Session, A]
type ActionT[A] = ReaderT[Option, Session, A]

val action: Action[String] = Reader(s => s)
val actionT: ActionT[String] = action mapK Option.apply
于 2016-06-05T13:22:50.840 に答える