Предположим, у меня есть следующая алгебра для работы с файловой системой:
sealed trait Fs[A]
case class Ls(path: String) extends Fs[Seq[String]]
case class Cp(from: String, to: String) extends Fs[Unit]
def ls(path: String) = Free.liftF(Ls(path))
def cp(from: String, to: String) = Free.liftF(Cp(from, to))
И следующий интерпретатор алгебры:
def fsInterpreter = new (Fs ~> IO) {
def apply[A](fa: Fs[A]) = fa match {
case Ls(path) => IO(Seq(path))
case Cp(from, to) => IO(())
}
}
Теперь предположим, что я хочу построить другую алгебру, использующую первую. Например.:
sealed trait PathOps[A]
case class SourcePath(template: String) extends PathOps[String]
def sourcePath(template: String) = Free.liftF(SourcePath(template))
Следующее, что я хочу написать, - интерпретатор для PathOps ~> IO
, который делал бы что-то вроде этого:
for {
paths <- ls(template)
} yield paths.head
Другими словами, мой интерпретатор для PathOps
должен обращаться к Fs
алгебре.
Как мне это сделать?
PathOps ~> Free[Fs, ?]
иFs ~> IO
? То есть: ваш желаемый естественный трафаретPathOps ~> IO
каким-то образом учитываетсяFree[Fs, ?]
-монадой? - person Andrey Tyukin   schedule 12.03.2018