Created
April 20, 2020 21:59
-
-
Save blast-hardcheese/201ebc6dff33a7bdebb4b65fa57077de to your computer and use it in GitHub Desktop.
Example code to go along with the guardrail internals talk on LanguageAbstraction from https://www.youtube.com/playlist?list=PL5ecYVRYIkSGtui_rZkXNXCRIWlTFdaGr
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.math.BigInteger | |
import cats._, cats.implicits._ | |
trait TypeBag { | |
type Number | |
type String | |
} | |
trait HighLevel extends TypeBag { | |
type Number = BigInteger | |
type String = java.lang.String | |
} | |
trait LowLevel extends TypeBag { | |
type Number = Byte | |
type String = Array[Byte] | |
} | |
abstract class Interface[TB <: TypeBag, F[_]] { | |
def getInput(): F[TB#String] | |
def parseString(input: TB#String): F[List[TB#Number]] | |
def pickNumber(nums: List[TB#Number]): F[Option[TB#Number]] | |
} | |
implicit object HighLevelInterface extends Interface[HighLevel, cats.Id] { | |
def getInput(): String = scala.io.StdIn.readLine("Input: ") | |
def parseString(input: String): List[BigInteger] = input.split(',').map(x => new BigInteger(x.trim)).toList | |
def pickNumber(nums: List[BigInteger]): Option[BigInteger] = nums.headOption | |
} | |
implicit object LowLevelInterface extends Interface[LowLevel, cats.Id] { | |
def getInput(): Array[Byte] = { | |
println("Enter bytes, terminated by -1") | |
@scala.annotation.tailrec | |
def consumeAll(acc: Array[Byte]): Array[Byte] = { | |
val next = scala.io.StdIn.readByte() | |
if (next == -1) acc | |
else consumeAll(acc :+ next) | |
} | |
consumeAll(new Array(0)) | |
} | |
def parseString(input: Array[Byte]): List[Byte] = input.toList | |
def pickNumber(nums: List[Byte]): Option[Byte] = nums.headOption | |
} | |
object Work { | |
def doWork[TB <: TypeBag, F[_]: Monad](implicit I: Interface[TB, F]): F[Option[TB#Number]] = { | |
for { | |
input <- I.getInput() | |
parsed <- I.parseString(input) | |
picked <- I.pickNumber(parsed) | |
} yield picked | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment