Skip to content

Instantly share code, notes, and snippets.

@ryoppy
Created January 12, 2015 23:04
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 ryoppy/36a39f43a7ef40189e36 to your computer and use it in GitHub Desktop.
Save ryoppy/36a39f43a7ef40189e36 to your computer and use it in GitHub Desktop.
めも
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