2015-09-24 5 views
20

私はScalaのフリーモナドについて学んでおり、私はネコを使ってフリーモナドに持ちこたえることができる簡単な代数の例をまとめました。Scalaのフリーモナドでのモナド効果の積み上げ

は、ここに私の代数

sealed trait ConsultationOp[A] 
object consultation { 
    case class Create(c: Consultation) extends ConsultationOp[Unit] 
    case class Get(s: ConsultationId) extends ConsultationOp[Option[Consultation]] 
} 

だと私はFreeからConsultationOpからリフティングが暗黙的に実行される

def app = for { 
    c <- consultation.Create(Consultation("123", "A consultation")) 
    _ <- consultation.Get(c._id) 
} yield() 

def interpreters = ConsultationInterpreter or UserInterpreter 
app.foldMap(interpreters) 

のようにそれを使用することができますよ。これまでのところ

とても良いが、何であれば、私はconsultation.Getによって返されたオプションの値を抽出する必要があります。

https://github.com/gabro/free-api不足している詳細の多くがあります、完全な作業実装はここにあります)。

心に来る最初の事はモナド変換子である、すなわち

def app = for { 
    c <- consultation.Create(Consultation("123", "A consultation")).liftM[OptionT] 
    d <- OptionT(consultation.Get(c._id)) 
    _ <- doSomethingAConsultation(d) 
} yield() 

のようなものが、それは醜い、それが右に感じることはありません。

無料のモナドを使用しているときにモナド効果を積み重ねる方法は何ですか?

+1

この[here](https://www.reddit.com/r/scala/comments/5p3fc3/free_monads_in_scala_web_stack_part_i/dco5yqy/)に関連する議論があります。要点は、Freeを使用しても、 'ConsultationOp'の中で' A'という値を扱うことが自由になるわけではないということです。 [freek](https://github.com/ProjectSeptemberInc/freek)や[eff](https://github.com/atnos-org/eff)のようなライブラリは、この問題をよりエレガントに解決します。 –

答えて

3

私はこれらの例に繰り返し見る一般的な方法は、あなたがの線に沿って、あなたのコード変更することができますので、トラバースを使用することです:

私見、モナド変換子の代替よりもはるかにきれいで、
import cats.syntax.traverse._ 
import cats.instances.option._ 

// ... 

def app = for { 
    c <- consultation.Create(Consultation("123", "A consultation")) 
    d <- consultation.Get(c._id) 
    _ <- d.traverseU(doSomethingAConsultation(_)) 
} yield() 

を。 importのコードを少し修正する必要があるかもしれませんが、私は試しませんでしたが、概念は:トラバースを使用することです。

+0

ありがとうございます!これは一般的な習慣(あなたの経験)ですか?あるいは、モナドをインタープリタに移動して、 'ConsultationOp'から(例えば)' Future [Option] 'に自然変換することがもっと一般的でしょうか? –

+0

私の中では、真実を伝えるのは些細なことですが、私はいつも「トラバース」を使ってこの種の問題を解決してきました。しかし、モナドスタッキングをインタプリタに移動することはオプションであり、いくつかのlibsはそれだけです。フリースタイル:https:///不運にも、私はそれをまだ完全に見る時間がなかった。 – lambdista

+0

ありがとう!それは理にかなっている。 –

関連する問題