2017-09-27 4 views
0

cats/monads/understandingの問題があります。Monad of Nothingはネコでは機能しません

for (...; nothing <- My[Nothing]()) yield nothing 

しかしtest22に示す障害が私の場合のためにcats.monadが使用できなくなります:私はtest12しかし、それはfor構文を可能に奇妙に見えることを実感

import cats._ 
import cats.implicits._ 

final case class My[T]() 
implicit val monadMy: Monad[My] = new Monad[My] { ... } 

// this compiles 
def test11[A, B](m: My[A], f: A => B): My[B] = m.map(f) 
// this fails: value map is not a member of My[Nothing] 
def test12[B](m: My[Nothing], f: Nothing => B): My[B] = m.map(f) 

// this compiles 
def test21[A, B](m: My[A], f: A => My[B]): My[B] = m.flatMap(f) 
// this fails: type mismatch; 
// [error] found : A => My[Nothing] 
// [error] required: A => My[B] 
def test22[A](m: My[A], f: A => My[Nothing]): My[Nothing] = m.flatMap(f) 

: 次のスニペットを考えてみてください。 Nothingのモナドはモナド法に違反していますか?

flatMapM[Nothing]にお伝えください。

ありがとうございます。

UPDATE私はへのアクセス権を持たない、私はMy共変をした場合には、この最小限のコードスニペットは、コンパイルだろうが、残念ながらもともと私はcats.Freeを使用しています。

UPDATEは、もう一つの回避策は、すなわち、どこでも、私はtest12が必要ですが、再び、私はM[Nothing]ための行動が他のタイプよりも異なっている理由を理解したいと思いますtest11を使用し、どこでも私はNothingを使うポリモーフィック機能を使用することです。

更新日私がNothingに変更した場合、 Intそれはコンパイルされます。ですから、これは設計によるものです。しかし、なぜ?

更新もう1つの回避策:scalazに切り替えます。

更新日問題はちょうどscalaに関連しています。

UPDATE回避方法:未定義の場合はtype Bottom <: Nothingを宣言し、代わりに使用してください。

+3

心のスイッチをオンにすると便利ですでした作成する?あなたは何を達成しようとしていますか? –

+0

例えばリストモナドが失敗した場合、全てが空リストになります。これは 'val failure:List [Nothing] = Nil'です。もちろん、私はdef failure [T]:List [T] = Nil'を実行してもうまくいくが、... –

+0

リストモナドの失敗はどういう意味ですか?わかりません。 –

答えて

1

MyTに共変量を作るようにしてください。その後、コードがコンパイルされます。不変T

final case class My[+T]() 

それは

Information:27.09.17 15:55 - Compilation completed with 2 errors and 0 warnings in 2s 804ms 
/home/dmitin/Projects/myproject/src/main/scala/App.scala 

Information:(19, 59) toFunctorOps is not a valid implicit value for m.type => ?{def map: ?} because: 
type mismatch; 
found : m.type (with underlying type App.My[Nothing]) 
required: App.My[A] 
Note: Nothing <: A, but class My is invariant in type T. 
You may wish to define T as +T instead. (SLS 4.5) 
    def test12[B](m: My[Nothing], f: Nothing => B): My[B] = m.map(f) 

Error:(19, 61) value map is not a member of App.My[Nothing] 
    def test12[B](m: My[Nothing], f: Nothing => B): My[B] = m.map(f) 

Error:(26, 73) type mismatch; 
found : A => App.My[Nothing] 
required: A => App.My[B] 
    def test22[A](m: My[A], f: A => My[Nothing]): My[Nothing] = m.flatMap(f) 

時にはそれはあなたができないタイプである `Nothing`のモナドを必要とする理由私が尋ねるscalacOptions += "-Xlog-implicits"

+1

これは助けになるだろうが、私はそれが共変ではないが、もともと私は 'cats.Free'を共変なものではなく2番目の引数として使うからです。私は私の質問を更新します。 –

関連する問題