このScalaコードを理解するのを手伝ってください:Scalaz Io MonadとInflicits

StackOverflow https://stackoverflow.com/questions/7419089

  •  30-10-2019
  •  | 
  •  

質問

これはフォローアップです これ 質問。

これが私が理解しようとしているコードです(それはからです http://apocalisp.wordpress.com/2010/10/17/scalaz-tutorial-enumeration-io-with-italees/):

object io {
  sealed trait IO[A] {
    def unsafePerformIO: A
  }

  object IO {
    def apply[A](a: => A): IO[A] = new IO[A] {
      def unsafePerformIO = a
    }
  }

  implicit val IOMonad = new Monad[IO] {
    def pure[A](a: => A): IO[A] = IO(a)
    def bind[A,B](a: IO[A], f: A => IO[B]): IO[B] = IO {
      implicitly[Monad[Function0]].bind(() => a.unsafePerformIO,
                                        (x:A) => () => f(x).unsafePerformIO)()
    }
  }
}

このコードはこのように使用されています(私は import io._ 暗示されています)

def bufferFile(f: File) = IO {   new BufferedReader(new FileReader(f)) }

def closeReader(r: Reader) = IO {   r.close }

def bracket[A,B,C](init: IO[A], fin: A => IO[B], body: A => IO[C]): IO[C] = for { a <- init
      c <- body(a)
      _ <- fin(a) }   yield c

def enumFile[A](f: File, i: IterV[String, A]): IO[IterV[String, A]] =  bracket(bufferFile(f),
          closeReader(_:BufferedReader),
          enumReader(_:BufferedReader, i))

私は今理解しようとしています implicit val IOMonad 意味。これが私がそれを理解する方法です。これは Scalaz.monad, 、したがって、定義する必要があります purebind の抽象値 scalaz.Monad 特性。

pure 値を取り、「コンテナ」タイプに含まれる値に変換します。たとえば、それを取ることができます Int aを返します List[Int]. 。これは非常に簡単に思えます。

bind 「コンテナ」タイプと、コンテナが保持するタイプを別のタイプにマップする関数を採用します。返される値は同じコンテナタイプですが、現在は新しいタイプを保持しています。例は、を取ることです List[Int] にマッピングします List[String] マップする関数を使用します Ints to Strings。は bind ほとんど同じです map?

の実装 bind 私が立ち往生しているところです。これがコードです:

def bind[A,B](a: IO[A], f: A => IO[B]): IO[B] = IO {
  implicitly[Monad[Function0]].bind(() => a.unsafePerformIO,
      (x:A) => () => f(x).unsafePerformIO)()
}

この定義には必要です IO[A] マップします IO[B] を取る関数を使用します A と返します IO[B]. 。私はこれを行うために、それは使用する必要があると思います flatMap 結果を「フラット化」する(正しい?)。

= IO { ... } と同じです

 = new IO[A] {
  def unsafePerformIO = implicitly[Monad[Function0]].bind(() => a.unsafePerformIO,
      (x:A) => () => f(x).unsafePerformIO)()
  }
}

おもう?

implicitly メソッドは、実装する暗黙の値(値、右?)を探します Monad[Function0]. 。この暗黙の定義はどこから来たのですか?これはからだと思います implicit val IOMonad = new Monad[IO] {...} 定義ですが、私たちは今その定義の中にあり、物事は少し円形になり、私の脳は無限のループで立ち往生し始めます:)

また、最初の議論 bind (() => a.unsafePerformIO)パラメーターを取得せず、A.Unsafeperformioを返す関数のようです。これをどのように読むべきですか? bind コンテナタイプを最初の引数として取るので、多分 () => a.unsafePerformIO コンテナタイプに解決しますか?

正しい解決策はありません

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top