Friday, January 22, 2016

Let it be

From Beatles:

LET IT BE                       (Beatles)

                       G              D                 Em          Cmaj7    C6
                When I find myself in times of trouble, Mother Mary comes to me
                G                 D              C  G/B Am G
                Speaking words of wisdom, let it be


                And in my hour of darkness, She is standing right in front of me

                Speaking words of wisdom, Let it be

                        Em        G/D          C          G
                Let it be, let it be,  let it be, let it be
                G                D              C  G/B Am G
                Whisper words of wisdom, let it be


                And when the broken hearted people, Living in the world agree

                There will be an answer, let it be


                But though they may be parted, There is still a chance that they may see

                There will be an answer, let it be


        CHORUS: Let it be, let it be, let it be, let it be
           |
           |    There will be an answer, let it be
           |
           |    Let it be, let it be, let it be, let it be
           |
           |    Whisper words of wisdom, let it be
                                
                LEAD

                Let it be, let it be, let it be, let it be

                Whisper words of wisdom, let it be


                And when the night is cloudy, 
        
                There is still a light that shines on me

                Shine on till tomorrow, let it be


                I wake up to the sound of music, Mother Mary comes to me

                Speaking words of wisdom, let it be

                CHORUS

               chords in instrumental section and ending:


               C  G/B   Am   G   F  C/E  D   C   G

Wednesday, January 13, 2016

Firebase comment app in javascript

var firebaseData = new Firebase('https://burning-fire-9280.firebaseio.com');
var commentsDB = firebaseData.child("comments");
//commentsDB.transaction(function(currentval) {
//  return (currentval || 0) + 1;
//});

var getEpoch  = function() {
  return (new Date()).getTime();
}

var epochToDate = function(epoch) {
  var d = new Date(0);
  d.setUTCMilliseconds(epoch);
  return d;
}


var handleCommentKeypress = function (e) {
  if (e.keyCode == 13) {
    var author = $("#author-field").val();
    var comment = $("#comment-field").val();
    if (author && comment) {
      var date = new Date();
      date = date.toString();
      commentsDB.push(
        {author: author, comment: comment, date: getEpoch()}
      );
    } else {
      alert("Author and Comment are required fields!");
    }
  }
};

commentsDB.on("child_added", function (snap) {
  var entry = snap.val();
  var entryLI = $("<li></li>").text(
    entry.author + ": " + entry.comment + " [ " + epochToDate(entry.date).toString() + " ] "
  )
  $("#comments-list").append(entryLI);
  $("#comment-field").val("");
})

$("#comment-field").keypress(handleCommentKeypress)
$("#author-field").keypress(handleCommentKeypress)

var ref = new Firebase("https://dinosaur-facts.firebaseio.com/dinosaurs");
ref.orderByChild("height").on("child_added", function (snapshot) {
  console.log(snapshot.key() + " was " + snapshot.val().height + " meters tall");
});

Tuesday, January 12, 2016

Javascript variable hoisting

var type = 'Ring Tailed Lemur';
function Lemur() {
 console.log(type);
 var type = 'Ruffed Lemur';
}
Lemur();

is translated into

var type = 'Ring Tailed Lemur';
function Lemur() {
 var type;
 console.log(type);
 var type = 'Ruffed Lemur';
}
Lemur();

undefined is logged in this case.

Manipulate clipboard in Javascript

window.addEventListener('copy', function (ev) {
    console.log('copy event');
    // you can set clipboard data here, e.g.
    ev.clipboardData.setData('text/plain', 'some text pushed to clipboard');
    // you need to prevent default behaviour here, otherwise browser will overwrite your content with currently selected 
    ev.preventDefault();
});

Monday, January 11, 2016

Scala extractors

/**
  * Created by kaiyin on 1/10/16.
  */
object TestUnapply {
  case class Division(val number: Int) {
    def unapply(divider: Int): Option[(Int, Int)] = if (number % divider == 0) Some(number/divider, 0) else None
    def unapply(divider: Double): Boolean = number % divider.toInt == 0
  }


  val divisionOf15 = Division(15)
  val y = 5 match {
    case divisionOf15(z, w) => s"$z, $w"
    case _ => s"Not divisible"
  }

  val z = 5.0 match {
    case divisionOf15() => "Divisible"
    case _ => "Not divisible"
  }
}

Friday, January 8, 2016

Relation between join, fmap and bind

Recognizing the equivalence:

join (fmap f ma) = ma >>= f

Proof:


  join (fmap f ma)
  fmap f ma >>= id         -- join x = x >>= id                 (definition)
  (ma >>= return . f) >>= id
                           -- fmap f xs = xs >>= return . f              (1)
  ma >>= (\x -> (return . f) x >>= id)
                           -- m >>= (\x -> k x >>= h) = (m >>= k) >>= h  (2)
  ma >>= (\x -> return (f x) >>= id)
                           -- (f . g) x = f (g x)               (definition)
  ma >>= (\x -> id (f x))  -- return a >>= k = k a                       (3)
  ma >>= (\x -> f x)       -- id x = x                          (definition)
  ma >>= f                 --                                (eta reduction)

  (1) implied by monad laws
  (2) associativity monad law
  (3) left identity monad law
  

Credit to verement.

Monoid in scala

The monoid typeclass:

/**
  * Created by kaiyin on 1/8/16.
  */

object M {

  trait Monoid[A] {
    def append(a1: A, a2: A): A

    def empty: A
  }

  object Monoid {
    implicit def ListMonoid[A]: Monoid[List[A]] = new Monoid[List[A]] {
      def append(a1: List[A], a2: List[A]) = a1 ::: a2

      def empty = Nil
    }

    implicit def PairMonoid[A, B](implicit a: Monoid[A], b: Monoid[B]): Monoid[(A, B)] = new Monoid[(A, B)] {
      def append(ab1: (A, B), ab2: (A, B)) = (a.append(ab1._1, ab2._1), b.append(ab1._2, ab2._2))
      def empty = (a.empty, b.empty)
    }

    def append[A](a1: A, a2: A)(implicit m: Monoid[A]): A = m.append(a1, a2)
    def empty[A](implicit m: Monoid[A]) = m.empty
  }
}

import M.Monoid._
import M.Monoid

implicitly[Monoid[List[Int]]].append(List(1, 2), List(3, 4))

append(List(1, 2), List(3, 4))
append(List(List(1), List(2)), List(List(3), List(4)))
empty[List[String]]
append((List(1, 2), List(5, 6)), (List(3, 4), List(7, 8)))

Monday, January 4, 2016

Riding the knight in haskell

Caluclate possible moves of a knight on a chess board:

import Control.Monad as M

type KnightPos = (Int, Int)

moveKnight :: KnightPos -> [KnightPos]
moveKnight (c, r) = do
  (c', r') <- possibleMoves
  M.guard (c' `elem` [1..8] && r' `elem` [1..8])
  return (c', r')
    where
      possibleMoves = [
        \(a, b) (c, d) -> (c + a, d + b),
        \(a, b) (c, d) -> (c + a, d - b),
        \(a, b) (c, d) -> (c - a, d + b),
        \(a, b) (c, d) -> (c - a, d - b)
        ] <*> [(1, 2), (2, 1)] <*> [(c, r)]