Skip to content

Instantly share code, notes, and snippets.

@AitorATuin
Created April 3, 2013 12:58
Show Gist options
  • Save AitorATuin/5300994 to your computer and use it in GitHub Desktop.
Save AitorATuin/5300994 to your computer and use it in GitHub Desktop.
Walk the line example from 'http://learnyouahaskell.com/a-fistful-of-monads#walk-the-line' in scala. Birds using plain scala BirdZ using scalaz
package com.logikujo.scalazrepl
import scalaz._
import Scalaz._
object BirdsCommon {
type Pole = (Int, Int)
trait Direction
case object Left extends Direction
case object Right extends Direction
}
object Birds {
import BirdsCommon._
def landAny(dir:Direction)(n:Int)(pole:Pole):Option[Pole] = {
def land(pole:Pole):Option[Pole] = math.abs(pole._1 - pole._2) match {
case x if x < 4 => Some(pole)
case _ => None
}
if (dir == Left) land((pole._1 + n,pole._2))
else land(pole._1, pole._2 + n)
}
val landLeft = landAny(Left)_
val landRight = landAny(Right)_
/*
* scala> Some(0->0).flatMap(landRight(2)).flatMap(landLeft(2)).flatMap(landRight(2))
* res9: Option[(Int, Int)] = Some((2,4))
*
* scala> Some(0->0).flatMap(landLeft(1)).flatMap(landRight(4)).flatMap(landLeft(-1)).flatMap(landLeft(-2))
* res10: Option[(Int, Int)] = None
*
*/
}
object BirdZ {
import BirdsCommon._
def landAny(dir:Direction)(n:Int)(pole:Pole):Option[Pole] = {
def land(pole:Pole):Option[Pole] = (math.abs(pole._1 - pole._2) < 4) ? pole.some | none
(dir == Left) ? land((pole._1 + n) -> pole._2) | land(pole._1 -> (pole._2 + n))
}
val landLeft = landAny(Left)_
val landRight = landAny(Right)_
/*
* scala> (0,0).some >>= landRight(2) >>= landLeft(2) >>= landRight(2)
* res1: Option[(Int, Int)] = Some((2,4))
*
* scala> (0,0).some >>= landLeft(1) >>= landRight(4) >>= landLeft(-1) >>= landRight(-2)
* res4: Option[(Int, Int)] = None
*
*/
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment