Last active
July 29, 2018 05:12
-
-
Save afsalthaj/110e01322cc05ef6c7a1e6fa45e95dea 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
package io.atlassian.aws | |
import java.io.File | |
import scalaz.{Free, Functor} | |
sealed trait FileActionOp[A] | |
case class Pure[A](x: A) extends FileActionOp[A] | |
case class MakeDir[A](d: File, x: A) extends FileActionOp[A] | |
case class CreateFile[A](d: File, x: A) extends FileActionOp[A] | |
object X { | |
implicit val functorF: Functor[FileActionOp] = new Functor[FileActionOp] { | |
override def map[A, B](fa: FileActionOp[A])(f: A => B): FileActionOp[B] = | |
fa match { | |
case Pure(x) => Pure(f(x)) | |
case MakeDir(d, x) => MakeDir(d, f(x)) | |
case CreateFile(d, x) => CreateFile(d, f(x)) | |
} | |
} | |
type FileAction[A] = Free[FileActionOp,A] | |
val createFile: Free[FileActionOp, String] = Free.liftF(CreateFile(new File(""), "afsal")) | |
val makeDir: Free[FileActionOp, String] = Free.liftF(MakeDir(new File(""), "afsal")) | |
// My program is doing a lot of input and output operations. First it creates a file. Then it creates a directory. | |
// Please test if myProgram does the right thing! That it first createFile and then makeDir | |
val myProgram: Free[FileActionOp, Unit] = | |
for { | |
_ <- createFile | |
_ <- makeDir | |
} yield () | |
// Unwrapping the Free to a list of operations recursively. Yes it is a boiler plate. | |
// Come on, do you want to write to a file and test? | |
// Or do you want to make a file operation program and test ? In which case you can test only the final result which is Unit | |
// Or do you want to write this boiler plate and test if the program has all the steps that are required? | |
def inspectProgram[A](f: Free[FileActionOp,A]): List[FileActionOp[None.type]] = f.fold( | |
(a:A) => List(), | |
(x:FileActionOp[FileAction[A]]) => x match { | |
case Pure(x) => inspectProgram(x) | |
case MakeDir(d,x) => MakeDir(d,None) :: inspectProgram(x) | |
case CreateFile(d,x) => CreateFile(d,None) :: inspectProgram(x) | |
} | |
) | |
} | |
object Main { | |
def main(args: Array[String]): Unit = { | |
val s = X.inspectProgram[Unit](X.myProgram) | |
// M also worried about the order, and it tests that as well! | |
assert(s == List(CreateFile(new File(""), None), MakeDir(new File(""), None))) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment