Created
January 4, 2012 02:37
-
-
Save akihiro4chawon/1558173 to your computer and use it in GitHub Desktop.
arm arrow
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import scalaz._ | |
| import Scalaz._ | |
| import scala.util.control.Exception._ | |
| package com.github.akihiro4chawon.arm.arrow { | |
| // Resource から 最終製品までの供給網 | |
| trait SupplyChain[-T, +R] { | |
| def backorder[S](f: R => S, v: T): S | |
| def produce[S](v: T): R = backorder(identity, v) | |
| def either(v: T): Either[Throwable, R] = allCatch either produce(v) | |
| def opt(v: T): Option[R] = allCatch opt produce(v) | |
| } | |
| // 開け閉めが必要な Resource の供給 | |
| class ResourceSupply[-T, +R: Resource](open: T => R) extends SupplyChain[T, R] { | |
| override def backorder[S](f: R => S, v: T): S = { | |
| val h = open(v) | |
| try { f(h) } finally { implicitly[Resource[R]].close(h) } | |
| } | |
| } | |
| // 右から来たものを左へ受け流すでござる | |
| class Plant[-T, +R](assemble: T => R) extends SupplyChain[T, R] { | |
| override def backorder[S](f: R => S, v: T): S = (f compose assemble)(v) | |
| } | |
| // 下請け孫請け compose でござる | |
| class Tier[-T, +R, A](tier2: SupplyChain[T, A], tier1: SupplyChain[A, R]) extends SupplyChain[T, R] { | |
| override def backorder[S](f: R => S, v: T): S = tier1.backorder(f, tier2.backorder(identity, v)) | |
| } | |
| // Scalaz 向け型クラス | |
| trait SupplyChains { | |
| implicit val SupplyChainCategory: Category[SupplyChain] = new Category[SupplyChain] { | |
| def id[A] = new Plant[A, A](identity) | |
| def compose[X, Y, Z](f: SupplyChain[Y, Z], g: SupplyChain[X, Y]) = new Tier[X, Z, Y](g, f) | |
| } | |
| implicit val SupplyChainArrow: Arrow[SupplyChain] = new Arrow[SupplyChain] { | |
| override val category = SupplyChainCategory | |
| override def arrow[B, C](f: B => C) = new Plant(f) | |
| override def first[B, C, D](a: SupplyChain[B, C]) = new SupplyChain[(B, D), (C, D)] { | |
| override def backorder[S](f: ((C, D)) => S, v: (B, D)): S = | |
| a.backorder(c => f(c, v._2), v._1) // 本当は LazyTuple でないと、ArrowLoop とかで困る気がする(´・ω・`) | |
| } | |
| override def second[B, C, D](a: SupplyChain[B, C]) = new SupplyChain[(D, B), (D, C)] { | |
| override def backorder[S](f: ((D, C)) => S, v: (D, B)) = | |
| a.backorder(c => f(v._1, c), v._2) | |
| } | |
| } | |
| } | |
| } | |
| package com.github.akihiro4chawon.arm { | |
| package object arrow extends SupplyChains { | |
| def managed[T, R: Resource](open: T => R): SupplyChain[T, R] = new ResourceSupply(open) | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import com.github.akihiro4chawon.arm.arrow._ | |
| import scalaz._ | |
| import Scalaz._ | |
| object Main extends App { | |
| import java.io._ | |
| // なんの変哲もない部分 | |
| def copyStream(is: InputStream, os: OutputStream, buffSize: Int) { | |
| val buff = new Array[Byte](buffSize) | |
| var readSize = 0 | |
| while ({readSize = is.read(buff); readSize != -1}) | |
| os.write(buff, 0, readSize) | |
| } | |
| // Arrow のほうが本質的じゃねーの? | |
| val openInputStream = managed(new FileInputStream(_: String): InputStream) | |
| val openOutputStream = managed(new FileOutputStream(_: String): OutputStream) | |
| val copyFileFunc = (copyStream(_: InputStream, _: OutputStream, 512)).tupled | |
| val copyFileArrow = (openInputStream *** openOutputStream) >>^ copyFileFunc | |
| // ここで実際に発動する | |
| copyFileArrow.produce("input.txt" -> "output-arrow.txt") | |
| // ToDo: | |
| // ・ArrowLoop にする意味はあるのか? | |
| // ・ArrowApply -> Monad を導出して Arrow と Monad の関係を理解する。 | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment