Created
October 31, 2014 15:31
-
-
Save landonf/f07cfedd92aea25f419c 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 java.io.IOException | |
import java.nio.channels.FileChannel | |
import java.nio.file.{Path, Paths, StandardOpenOption} | |
import scodec.bits.BitVector | |
import shapeless.ops.hlist | |
import scalaz.{-\/, \/, \/-} | |
type AnalysisScore = Int | |
//type DataAnalysis[T] = (DataType, AnalysisScore) | |
type DataError = String | |
case class DataCursor[T] () | |
object DataLink { | |
import shapeless._ | |
implicit class DataLinkHListSyntax[I, O <: HList] (self: DataLink[I, O]) { | |
def composedHList (implicit last : hlist.Last[O]) : DataLink[I, last.Out] = self.map(l => last(l)) | |
} | |
} | |
case class DataLink[I, O] (follow: I => DataError \/ O) { | |
import shapeless._ | |
def ::[LI] (lhs: DataLink[LI, I]): DataLink[LI, I :: O :: HNil] = lhs.flatMap { firstVal => | |
this.map(firstVal :: _ :: HNil).follow(firstVal) | |
} | |
def ~> [B] (rhs: DataLink[O, B]): DataLink[I, B] = flatMap { firstVal => | |
rhs.follow(firstVal) | |
} | |
def map[B] (f: O => B): DataLink[I, B] = DataLink[I, B] { input => | |
DataLink.this.follow(input).map(f) | |
} | |
def flatMap[B] (f: O => DataError \/ B): DataLink[I, B] = DataLink[I, B] { input:I => | |
DataLink.this.follow(input).flatMap { data => | |
f(data) | |
} | |
} | |
} | |
val stringToInt = DataLink { str:String => \/-(str.toInt) } | |
val intToBool = DataLink { int:Int => \/-(true) } | |
val nested = stringToInt :: intToBool | |
// Demonstrating type-safe access of the full path | |
\/-(42) == nested.follow("42").map { value => | |
val intVal:Int = value(0) | |
val boolVal:Boolean = value(1) | |
if (boolVal) | |
intVal + 42 | |
else | |
0 | |
} | |
// Collapsing of HLists representing the full path to a composition of just FirstInput => FinalOutput | |
nested.follow("42").map(_.last) == nested.composedHList.follow("42") | |
// Combining of DataLinks to produce a decoding flow. | |
val stringToPath = DataLink { str:String => \/-(Paths.get(str)) } | |
val pathToChannel = DataLink { path:Path => | |
try { | |
\/-(FileChannel.open(path, StandardOpenOption.READ)) | |
} catch { | |
case ioe:IOException => -\/(s"Could not open file $path: ${ioe.getMessage}") | |
} | |
} | |
val channelToBitVector = DataLink { c:FileChannel => \/-(BitVector.fromMmap(c)) } | |
val httpLog = stringToPath :: (pathToChannel ~> channelToBitVector ~> DataLink { v => | |
babelfish.codecs.sslsplit.http.decode(v).map(_._2) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment