Scalaz Reader 转换为 ReaderT

3

有一个我无法更改的函数返回 Scalaz Reader

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
1个回答

2
简短回答:您可以使用mapKReader[A]ReaderT[Id, A]的类型别名,而ReaderT则是Kleisli的别名。Id[A]A相同。
Kleisli的ScalaDoc中,我们找到了mapKmapK
def mapK[N[_], C](f: (M[B]) => N[C]): Kleisli[N, A, C]

由于我们知道Reader[Session, A]Kleisli[Id, Session, A]是相同的,因此我们可以使用mapK转换为Kleisli[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

当我在寻找答案时,我发现ReaderReaderT是具有不同配置的Kleisli的别名,但我没有足够的脑力来连接这些点。感谢您指出这些内容。我理解了mapK签名,但您知道在哪里可以找到更多使用mapK的示例吗? - thlim
1
我认为没有很多例子,但是我认为签名相当自说明:使用函数M[B] => N[C]Kleisli[M, A, B]转到Kleisli[N, A, C]。只要您可以定义这样的函数,就可以使用mapK - Peter Neyens

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接