2017-09-01 12 views
3

"scalaz-core"%"7.2.14" StateTモナドの構成でfailoverの何らかの動作を作成しようとしています。StateT [どちらか] Scalazのフェイルオーバーあり

EitherT周りStateTモナドラップは、このように、それはモナド変換子です:

type Error = String 
type ErrOrT[T] = Error \/ T 
type State[T] = StateT[ErrOrT, String, T] 

これらのタイプのすべてには素晴らしい作品 - 私はEitherプラスStateの力を活用することができます。私はtryWithFailover法のようなものを作りたいまた

def func1: State[Int] = ??? 
def func2: State[Int] = ??? 
def func3: State[Int] = ??? 

val stateMonad = for { 
    res1 <- func1 
    res2 <- func2 
    res3 <- func3 
} yield res3 

:私は、エラーの場合には、短絡を持っており、1つのモナド組成物中に、私の国をスタックすることができます。これは、元State[T]モナドを返すか、インナーEitherTの場合にState[T]モナドをフォールバック左含まれています

def tryWithFailover[T](run: State[T])(failover: Error => State[T]): State[T] = ??? 

だから、結果としてチェーンは次のようになります。

val stateMonad = for { 
    res1 <- func1 
    res2 <- tryWithFailover(func2)(err => failover) 
    res3 <- func3 
} yield res3 

failoverはそれができないのと同じ値だった場合問題。私はmapT/mapKのメソッドを使用して内部モナドにアクセスし、その結果が左か右かをチェックすることができます。左の場合は、fallbackの値を持つ内部モナドを作り直すことができます。しかし、それは価値ではありません、それはモナドそのものなので、私はflatMapTのようなものが必要です。

私は何かが恋しくなっていますか?フェールオーバーユーティリティ機能は私をたくさん助け、明示的にrunコールと真ん中のチェーンを壊したくない。


UPD:

値と

上記に言及フェイルオーバーは、次のように次のようになります。

def tryWithFailover[T](run: State[T])(failover: Error => T): State[T] = { 
    for { 
    lockedState <- State(st => (st, st)) 
    result <- run.mapT[ErrOrT, T, String] { 
     case [email protected] \/-(_) => ok 
     case -\/(error) => \/-((lockedState, failover(error))) 
    } 
    } yield result 
} 

UPD2:

悪い実装全体のモナドを破ります真ん中にrunとチェーン:私はアプローチを述べたという結論に達しましたいくつかの考慮後

def tryWithFailover[T](run: State[T])(failover: Error => State[T]): State[T] = { 
    for { 
    lockedState <- State(st => (st, st)) 
    result <- run.mapT[ErrOrT, T, String] { 
     case [email protected] \/-(_) => ok 
     case -\/(error) => failover(error).run(lockedState) 
    } 
    } yield result 
} 

答えて

0

は悪いことではありません。

def tryWithFailover[T](run: State[T])(failover: Error => State[T]): State[T] = { 
    for { 
    lockedState <- State(st => (st, st)) 
    result <- run.mapT[ErrOrT, T, String] { 
     case [email protected](_) => ok 
     case DLeft(error) => failover(error).run(lockedState) 
    } 
    } yield result 
} 

はいつか誰かが私の答えを修正しますように。

関連する問題