Skip to content

Instantly share code, notes, and snippets.

@tarao
Last active August 29, 2015 14:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tarao/1b36ce9e7ec861b051c3 to your computer and use it in GitHub Desktop.
Save tarao/1b36ce9e7ec861b051c3 to your computer and use it in GitHub Desktop.

ポイント

  • runするまではクエリは走らない
    • m*ms*ができた段階ではまだクエリは走ってない
  • 長いモナド型は途中の操作の種類を記憶している
    • N個のモナドに対する操作は同じ種類の操作でないといけない (というのを型が保証している)
    • 同じ種類の操作なので各ステップはまとめてやれる
  • Seq[モナド型]に対するrunは各ステップをまとめて実行
    • FlatMapped[]の場合はこのへん
      • ひとつ前までのモナドのリストをまとめてrun
      • 得られた結果をflatMap()に渡された関数fに施す (これはそれぞれ)
        • fはまたモナドを返す
        • fの中ではモナドを作るだけ(toCrankshaft等)でクエリはまだ走らない
      • fが返したモナドを集めたリストをふたたびまとめて実行
    • Resolve[]の場合はこのへん
      • Resolve[]toEnginetoCrankshaftしたときに作られる(HasA.Monadicが返すもの)
      • toEnginetoCrankshaftのレシーバの値をもっている
      • レシーバの値を集めてリストにしたものをHasA.map()にまとめて渡すことでrunする
      • 渡す先のHasAインスタンスはモナドのリストの先頭のもの

些細な注意点

  • FlatMapped[]Resolve[], Unit[]は実際は基底型のSig[]で表されていたりもします (わかりやすいように具体的に書きました)
val car: Car = ...
val m1 = car.toEngine
// m1 : Resolve[Engine, Car]
val engine1: Option[Engine] = m1.run
val m2 = car.toEngine map { e => e }
// m2 : FlatMapped[Engine, Engine, Unit[Engine], Resolve[Engine, Car]]
val engine2: Option[Engine] = m2.run
val m3 = car.toEngine flatMap { e => e.toCrankshaft }
// m3 : FlatMapped[Crankshaft, Engine, Resolve[Crankshaft, Engine], Resolve[Engine, Car]]
val crankshaft3: Option[Crankshaft] = m3.run
val m4 = car.toEngine flatMap { e => e.toCrankshaft } map { c => c }
// m4 : FlatMapped[Crankshaft, Engine, FlatMapped[Crankshaft, Crankshaft, Unit[Crankshaft], Resolve[Crankshaft, Engine]], Resolve[Engine, Car]]
val crankshaft4: Option[Crankshaft] = m4.run
val cars: Seq[Car] = ...
val ms1 = cars map { car => car.toEngine }
// ms1 : Seq[Resolve[Engine, Car]]
val engines1: Seq[Engine] = ms1.run
val ms2 = cars map { car => car.toEngine map { e => e } }
// ms2 : Seq[FlatMapped[Engine, Engine, Unit[Engine], Resolve[Engine, Car]]]
val engines2: Option[Engine] = ms2.run
val ms3 = cars map { car => car.toEngine flatMap { e => e.toCrankshaft } }
// ms3 : Seq[FlatMapped[Crankshaft, Engine, Resolve[Crankshaft, Engine], Resolve[Engine, Car]]]
val crankshafts3: Seq[Crankshaft] = ms3.run
val ms4 = cars map { car => car.toEngine flatMap { e => e.toCrankshaft } map { c => c } }
// ms4 : Seq[FlatMapped[Crankshaft, Engine, FlatMapped[Crankshaft, Crankshaft, Unit[Crankshaft], Resolve[Crankshaft, Engine]], Resolve[Engine, Car]]]
val crankshafts4: Seq[Crankshaft] = ms4.run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment