Skip to content

Instantly share code, notes, and snippets.

@seraphr
seraphr / hasCtor.scala
Created February 17, 2014 22:25
scalaのリフレクションで、コンストラクタの有無を確認するコード
import scala.reflect.runtime.universe._
class TypeCheck[T: WeakTypeTag]{
val mClassType = implicitly[WeakTypeTag[T]].tpe
val mConstructors = mClassType.members.filter(_.isMethod).map(_.asMethod).filter(_.isConstructor)
val mConstructorsParams = mConstructors.map(_.paramss.flatten.map(_.typeSignature))
def of[A: WeakTypeTag](a: A): Boolean = {
@seraphr
seraphr / CtorMacro.scala
Created February 18, 2014 10:36
scalaのdefマクロでコンストラクタ呼び出しコード生成
import scala.reflect.macros.Context
import scala.language.experimental.macros
object InitializeMacro{
def init[T, A, B](a: A, b: B) = macro initImpl[T, A, B]
def initImpl[T: c.WeakTypeTag, A: c.WeakTypeTag ,B: c.WeakTypeTag](c: Context)(a: c.Expr[A], b: c.Expr[B]): c.Expr[T] = {
import c.universe._
val tType = implicitly[WeakTypeTag[T]].tpe
scala> case class Base(id: String, data: String)
defined class Base
scala> case class Merged(id: String, dataList: Seq[String])
defined class Merged
scala>
scala> val tSeq = Seq(Base("c", "c2"), Base("a", "a1"), Base("c", "c3"), Base("a", "a2"), Base("b", "b"), Base("c", "c1"))
tSeq: Seq[Base] = List(Base(c,c2), Base(a,a1), Base(c,c3), Base(a,a2), Base(b,b), Base(c,c1))
@seraphr
seraphr / foldRight.scala
Created July 11, 2015 18:42
foldRightのfoldLeftを用いた実装。 ついでにstackless
def foldRightSimple[A, B](l: List[A])(z: B)(f: (A, B) => B): B = l match {
case Nil => z
case x :: xs => f(x, foldRightSimple(xs)(z)(f))
}
trait Trampoline[T]
case class Done[T](v: T) extends Trampoline[T]
case class Suspend[T](f: () => Trampoline[T]) extends Trampoline[T]
@annotation.tailrec
@seraphr
seraphr / TreeFold.scala
Created July 11, 2015 19:17
Treeのfoldと、それを用いた各種関数実装
trait Tree[A]
case class Leaf[A](v: A) extends Tree[A]
case class Branch[A](l: Tree[A], r: Tree[A]) extends Tree[A]
def fold[A, B](t: Tree[A])(map: A => B, construct: (B, B) => B): B = t match {
case Leaf(v) => map(v)
case Branch(l, r) => construct(fold(l)(map, construct), fold(r)(map, construct))
}
@seraphr
seraphr / OptionTraverse.scala
Created July 12, 2015 06:47
fp in scala EXERCISE 4.5
def traverse[A, B](a: List[A])(f: A => Option[B]): Option[List[B]] = a match {
case x :: xs =>
for {
y <- f(x)
ys <- traverse(xs)(f)
} yield y :: ys
case _ =>
Some(Nil)
}
@seraphr
seraphr / StreamFunctionsViaFoldRight.scala
Last active August 29, 2015 14:24
fp in scala EXERCISE 5.6 foldRightを用いたheadOptionの実装
def foldRight[A, B](s: Stream[A])(z: => B)(f: (A, => B) => B): B = s match {
case x #:: xs => f(x, foldRight(xs)(z)(f))
case _ => z
}
def headOptionViaFoldRight[A](s: Stream[A]): Option[A] = foldRight(s)(None: Option[A]) {
(e, acc) => Some(e)
}
def map[A, B](s: Stream[A])(f: A => B): Stream[B] = foldRight(s)(Stream.empty[B]) {
@seraphr
seraphr / StreamFuncs.scala
Created July 12, 2015 08:48
fp in scala EXERCISE 5.11 5.12 5.13 5.14 5.16 unfold関係+scanRight
def unfold[A, S](s: S)(f: S => Option[(A, S)]): Stream[A] = f(s) match {
case Some((a, s1)) => a #:: unfold(s1)(f)
case _ => Stream.empty[A]
}
def fibs: Stream[Int] = 0 #:: 1 #:: unfold((0, 1)) {
case (n0, n1) =>
val n2 = n0 + n1
Option((n2, (n1, n2)))
}
@seraphr
seraphr / State.scala
Last active August 29, 2015 14:24
fp in scala EXERCISE 6.6 6.7 map2とsequenceの実装
trait RNG {
def nextInt: (Int, RNG)
}
object RNG {
case class Simple(seed: Long) extends RNG {
def nextInt: (Int, RNG) = {
val newSeed = (seed * 0x5DEECE66DL + 0xBL) & 0xFFFFFFFFFFFFL // `&` is bitwise AND. We use the current seed to generate a new seed.
val nextRNG = Simple(newSeed) // The next state, which is an `RNG` instance created from the new seed.
val n = (newSeed >>> 16).toInt // `>>>` is right binary shift with zero fill. The value `n` is our new pseudo-random integer.
@seraphr
seraphr / CandyMachine.scala
Created July 13, 2015 19:40
fp in scala EXERCISE 6.11 CandyMachineの実装
case class State[S, +A](run: S => (A, S)) {
def map[B](f: A => B): State[S, B] = State { s0 =>
val (a, s1) = run(s0)
(f(a), s1)
}
def map2[B, C](that: State[S, B])(f: (A, B) => C): State[S, C] = State { s0 =>
val (a, s1) = this.run(s0)
val (b, s2) = that.run(s1)
(f(a, b), s2)