Created
January 12, 2015 23:04
-
-
Save ryoppy/36a39f43a7ef40189e36 to your computer and use it in GitHub Desktop.
めも
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._, Scalaz._ | |
// Tree | |
// Tree構造。TreeLocを使うとDOMのように多彩なアクセスができる。 | |
// ================== | |
locally { | |
val tree = 'A'.node( | |
'B'.node( | |
'C'.leaf | |
), | |
'D'.node( | |
'E'.leaf | |
) | |
) | |
val r = tree match { | |
case Tree.Node(a, Stream( | |
Tree.Node(b, Stream(c)), d)) => c.rootLabel | |
} | |
assert(r === 'C') | |
assert(tree.loc.getChild(1).map(_.getLabel) === 'B'.some) | |
assert(tree.loc.getChild(2).map(_.getLabel) === 'D'.some) | |
assert(tree.loc.find(_.getLabel === 'C').map(_.getLabel) === 'C'.some) | |
assert(tree.loc.firstChild.map(_.getLabel) === 'B'.some) | |
/* | |
scala> tree.draw.foreach(println) | |
A | |
| | |
+- B | |
| | | |
| `- C | |
| | |
`- D | |
| | |
`- E | |
*/ | |
} | |
// Zipper | |
// Zipper[Stream[A], A, Stream[A]] 。ずらしたりできる。 | |
// ================== | |
locally { | |
val z = Stream(1,2,3).toZipper | |
val r = z >>= {_.next} >>= {_.modify{_ => 4}.some} | |
assert(r.map(_.focus) === 4.some) | |
assert(r.map(_.shows) === "Zipper(Stream(1), 4, Stream(3))".some) | |
} | |
// Id | |
// Idモナド。結果をモナドで包まずに返す。 | |
// ================== | |
locally { | |
assert((1 |> {_ + 1}) === 2) | |
assert((1 visit {case x @ (1 | 2) => (x + 1).some}) === 2.some) | |
} | |
// Reader | |
// 実体はKleisliで、Reader[A, B] = Kleisli[Id, A, B]。 | |
// ================== | |
locally { | |
def config(key: String) = Kleisli[Option, Map[String, String], String](_ get key) | |
val template = for { | |
host <- config("host") | |
user <- config("user") | |
} yield (host, user) | |
val kv = Map("host" -> "localhost", "user" -> "root") | |
assert(template(kv) === ("localhost", "root").some) | |
} | |
// Lens | |
// Getter/Setter。 | |
// Lens : A => Store[B, A] | |
// Store : (F[A => B], I) | |
// ================== | |
locally { | |
case class Pos(x: Int, y: Int) | |
case class Elem(name: String, xy: Pos) | |
val div = Elem("<div>", Pos(0, 0)) | |
// move | |
val changedDiv = div.copy( | |
xy = div.xy.copy(0, 100) | |
) | |
// use lens | |
val changePos = Lens.lensu[Elem, Pos]((elem, pos) => elem.copy(xy = pos), _.xy) | |
val changeXY = Lens.lensu[Pos, (Int, Int)]( | |
{ case (pos, (x, y)) => pos.copy(x = x, y = y) }, | |
{ case Pos(x, y) => (x, y) } | |
) | |
// andThen : Elem -> Pos -> (Int, Int) をつなげる | |
val change: Lens[Elem, (Int, Int)] = changePos >=> changeXY | |
assert(change.set(div, (0, 100)) == changedDiv) | |
// Lens[A, B] = LensFamily[A1, A2, B1, B2] | |
// map : >-[C](f: B1 => C): State[A1, C] | |
val c: State[Elem, Pos] = change >- { case (x, y) => Pos(x + 1, y + 1) } | |
assert(c(div) == (div,Pos(1,1))) | |
// mod : mod(f: B1 => B2, a: A1): A2 | |
val e: Elem = change.mod({ case (x, y) => (x + 1, y) }, div) | |
assert(e == div.copy(xy = Pos(1, 0))) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment