PointerChain provided by Greg Pfeil github.com/sellout
This commit is contained in:
parent
8b52321920
commit
b5efa9c7f5
8 changed files with 258 additions and 124 deletions
|
@ -38,6 +38,7 @@ lazy val tagless = (project in file("tagless")).settings(
|
|||
"com.chuusai" %% "shapeless" % "2.3.3",
|
||||
"org.typelevel" %% "cats-core" % "2.1.1",
|
||||
"org.typelevel" %% "cats-effect" % "2.1.3",
|
||||
"org.typelevel" %% "cats-collections-core" % "0.9.0",
|
||||
"io.chrisdavenport" %% "fuuid" % "0.4.0",
|
||||
"io.higherkindness" %% "droste-core" % "0.8.0",
|
||||
"org.scalameta" %% "munit" % "0.7.9" % Test,
|
||||
|
|
|
@ -9,11 +9,11 @@ import scodec.stream.{StreamDecoder, StreamEncoder}
|
|||
object Main extends IOApp {
|
||||
|
||||
override def run(args: List[String]): IO[ExitCode] = {
|
||||
(Stream.resource(Blocker[IO]) >>= write[IO]).compile.drain.as(ExitCode.Success)
|
||||
(Stream.resource(Blocker[IO]) >>= read[IO]).compile.drain.as(ExitCode.Success)
|
||||
}
|
||||
|
||||
def read[F[_] : RaiseThrowable : Sync : ContextShift](blocker: Blocker): Stream[F, Unit] = {
|
||||
val input = Paths.get("""C:\Users\aprim\Documents\FancadeLevels\MetaWires""")
|
||||
val input = Paths.get("""C:\Users\aprim\Documents\FancadeLevels\TaglessTest""")
|
||||
io.file.readAll[F](input, blocker, 1024)
|
||||
.through(StreamDecoder.once(Codecs.encCartridge).toPipeByte)
|
||||
.evalMap(c => Sync[F].delay(println(c)))
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
package tf.bug.fancadetagless
|
||||
|
||||
import cats._
|
||||
import cats.implicits._
|
||||
import higherkindness.droste._
|
||||
import polymorphic._
|
||||
import tf.bug.fancadegraph.PinDefinition
|
||||
import tf.bug.fancadegraph.Level
|
||||
import tf.bug.fancadegraph.Block
|
||||
import tf.bug.fancadegraph.Template
|
||||
import tf.bug.fancadescodec.Position
|
||||
|
||||
sealed trait Fancade[A] {
|
||||
val template: Exists[Template]
|
||||
val pins: Vector[PinDefinition]
|
||||
}
|
||||
|
||||
object Fancade {
|
||||
|
||||
implicit val fancadeFunctor: Functor[Fancade] = new Functor[Fancade] {
|
||||
override def map[A, B](fa: Fancade[A])(f: A => B): Fancade[B] =
|
||||
fa match {
|
||||
case Capture(template, pins) =>
|
||||
Capture(template, pins)
|
||||
case Use(children, template, inputs, pins) =>
|
||||
Use(children.map(f), template, inputs, pins)
|
||||
}
|
||||
}
|
||||
|
||||
case class Capture[A](template: Exists[Template], pins: Vector[PinDefinition]) extends Fancade[A]
|
||||
case class Use[A](children: Vector[A], template: Exists[Template], inputs: Vector[PinDefinition], pins: Vector[PinDefinition]) extends Fancade[A]
|
||||
|
||||
def flatten: Algebra[Fancade, PointerChain[Fancade]] = Algebra {
|
||||
case Capture(template, pins) =>
|
||||
PointerChain.single(Capture(template, pins))
|
||||
case Use(children, template, inputs, pins) =>
|
||||
???
|
||||
}
|
||||
val stack: FancadeF => PointerChain[Fancade] = scheme.cata(flatten)
|
||||
def render(f: FancadeF): Level = {
|
||||
val pointerChain = stack(f)
|
||||
val blocks = pointerChain.map {
|
||||
case (ind, fc) =>
|
||||
Block(
|
||||
Position(0, ind, 0),
|
||||
fc.template
|
||||
)
|
||||
}
|
||||
|
||||
Level(
|
||||
blocks.toSet,
|
||||
???
|
||||
)
|
||||
}
|
||||
|
||||
}
|
85
tagless/src/main/scala/tf/bug/fancadetagless/FancadeF.scala
Normal file
85
tagless/src/main/scala/tf/bug/fancadetagless/FancadeF.scala
Normal file
|
@ -0,0 +1,85 @@
|
|||
package tf.bug.fancadetagless
|
||||
|
||||
import cats._
|
||||
import cats.implicits._
|
||||
import higherkindness.droste.data._
|
||||
import polymorphic._
|
||||
import scalax.collection.Graph
|
||||
import scalax.collection.GraphEdge.DiHyperEdge
|
||||
import tf.bug.fancadegraph.Block
|
||||
import tf.bug.fancadegraph.Level
|
||||
import tf.bug.fancadegraph.Pin
|
||||
import tf.bug.fancadegraph.PinDefinition
|
||||
import tf.bug.fancadegraph.Template
|
||||
import tf.bug.fancadescodec.Position
|
||||
|
||||
sealed trait FancadeF[A] {
|
||||
val template: Exists[Template]
|
||||
val pins: Vector[PinDefinition]
|
||||
}
|
||||
|
||||
object FancadeF {
|
||||
|
||||
implicit val fancadeTraverse: Traverse[FancadeF] = new Traverse[FancadeF] {
|
||||
override def traverse[G[_]: Applicative, A, B](fa: FancadeF[A])(f: A => G[B]): G[FancadeF[B]] =
|
||||
fa match {
|
||||
case Capture(t, p) => Capture[B](t, p).pure[G].widen
|
||||
case Use(c, t, i, o) =>
|
||||
c.traverse(f).map { newC => Use(newC, t, i, o) }
|
||||
}
|
||||
|
||||
override def foldLeft[A, B](fa: FancadeF[A], b: B)(f: (B, A) => B): B =
|
||||
fa match {
|
||||
case Capture(_, _) => b
|
||||
case Use(c, _, _, _) => c.foldLeft(b)(f)
|
||||
}
|
||||
|
||||
override def foldRight[A, B](fa: FancadeF[A], lb: Eval[B])(f: (A, Eval[B]) => Eval[B]): Eval[B] =
|
||||
fa match {
|
||||
case Capture(_, _) => lb
|
||||
case Use(c, _, _, _) => Traverse[Vector].foldRight(c, lb)(f)
|
||||
}
|
||||
}
|
||||
|
||||
case class Capture[A](template: Exists[Template], pins: Vector[PinDefinition]) extends FancadeF[A]
|
||||
case class Use[A](children: Vector[A], template: Exists[Template], inputs: Vector[PinDefinition], pins: Vector[PinDefinition]) extends FancadeF[A]
|
||||
|
||||
def render(f: Fix[FancadeF]): Level = {
|
||||
val pc = PointerChain.deduplicate[Id, FancadeF](f)
|
||||
val pcvi = pc.vertices.zipWithIndex
|
||||
val blocks: Set[Block] = pcvi.map {
|
||||
case (block, y) =>
|
||||
Block(
|
||||
Position(0, y, 0),
|
||||
block.template
|
||||
)
|
||||
}.toSet
|
||||
val wires: Graph[Pin, DiHyperEdge] =
|
||||
pcvi.foldLeft(Graph.empty[Pin, DiHyperEdge]) {
|
||||
case (graph, (block, y)) =>
|
||||
block match {
|
||||
case Capture(_, _) => graph
|
||||
case Use(children, template, inputs, _) =>
|
||||
val thisBlock = Block(
|
||||
Position(0, y, 0),
|
||||
template
|
||||
)
|
||||
val thesePins = inputs.map(Pin(thisBlock, _))
|
||||
val childrenPins: Vector[Pin] = children.flatMap { child =>
|
||||
val childInst = pc.vertices(child)
|
||||
val childBlock = Block(
|
||||
Position(0, child, 0),
|
||||
childInst.template
|
||||
)
|
||||
childInst.pins.map(Pin(childBlock, _))
|
||||
}
|
||||
val newEdges: Vector[DiHyperEdge[Pin]] = childrenPins.zip(thesePins).map {
|
||||
case (from, to) => DiHyperEdge(from, to)
|
||||
}
|
||||
graph ++ newEdges
|
||||
}
|
||||
}
|
||||
Level(blocks, wires)
|
||||
}
|
||||
|
||||
}
|
|
@ -55,6 +55,8 @@ trait Fanscript[F[_]] {
|
|||
def onBoxArt(onBoxArt: F[Unit]): F[Unit]
|
||||
def onTouch(onTouch: F[Fanscript.Touch] => F[Unit]): F[Unit]
|
||||
|
||||
def addNumbers(a: F[Float], b: F[Float]): F[Float]
|
||||
|
||||
def screenSizeWidth(screenSize: F[ScreenSize]): F[Float]
|
||||
def screenSizeHeight(screenSize: F[ScreenSize]): F[Float]
|
||||
|
||||
|
@ -79,30 +81,30 @@ object Fanscript {
|
|||
def run[F[_]](implicit interp: Fanscript[F]): F[R]
|
||||
}
|
||||
|
||||
implicit object fancade extends Fanscript[FancadeW] {
|
||||
implicit object fancade extends Fanscript[Fancade] {
|
||||
|
||||
override def lift(value: Float): FancadeW[Float] =
|
||||
Fix(Fancade.Capture(
|
||||
override def lift(value: Float): Fancade[Float] =
|
||||
Fix(FancadeF.Capture(
|
||||
Exists(Template(
|
||||
BlockDefinition.NumberValue,
|
||||
value
|
||||
)),
|
||||
Vector(BlockDefinition.NumberValue.output)
|
||||
))
|
||||
override def lift(value: Vector3): FancadeW[Vector3] = ???
|
||||
override def lift(value: Rotation): FancadeW[Rotation] = ???
|
||||
override def lift(value: Boolean): FancadeW[Boolean] = ???
|
||||
override def lift(value: Vector3): Fancade[Vector3] = ???
|
||||
override def lift(value: Rotation): Fancade[Rotation] = ???
|
||||
override def lift(value: Boolean): Fancade[Boolean] = ???
|
||||
|
||||
override def win(stop: Boolean): FancadeW[Unit] = ???
|
||||
override def lose(stop: Boolean): FancadeW[Unit] = ???
|
||||
override def setScore(score: FancadeW[Float]): FancadeW[Unit] = ???
|
||||
override def setCamera(position: FancadeW[Vector3], rotation: FancadeW[Rotation], distance: FancadeW[Float]): FancadeW[Unit] = ???
|
||||
override def setLight(position: FancadeW[Vector3], rotation: FancadeW[Rotation]): FancadeW[Unit] = ???
|
||||
override def screenSize: FancadeW[ScreenSize] = ???
|
||||
override def accelerometer: FancadeW[Vector3] = ???
|
||||
override def win(stop: Boolean): Fancade[Unit] = ???
|
||||
override def lose(stop: Boolean): Fancade[Unit] = ???
|
||||
override def setScore(score: Fancade[Float]): Fancade[Unit] = ???
|
||||
override def setCamera(position: Fancade[Vector3], rotation: Fancade[Rotation], distance: Fancade[Float]): Fancade[Unit] = ???
|
||||
override def setLight(position: Fancade[Vector3], rotation: Fancade[Rotation]): Fancade[Unit] = ???
|
||||
override def screenSize: Fancade[ScreenSize] = ???
|
||||
override def accelerometer: Fancade[Vector3] = ???
|
||||
|
||||
override def getPosition(obj: FancadeW[Obj]): FancadeW[Position] =
|
||||
Fix(Fancade.Use(
|
||||
override def getPosition(obj: Fancade[Obj]): Fancade[Position] =
|
||||
Fix(FancadeF.Use(
|
||||
Vector(obj),
|
||||
Exists(Template(
|
||||
BlockDefinition.GetPosition,
|
||||
|
@ -111,53 +113,64 @@ object Fanscript {
|
|||
Vector(BlockDefinition.GetPosition.obj),
|
||||
Vector(BlockDefinition.GetPosition.position)
|
||||
))
|
||||
override def setPosition(obj: FancadeW[Obj], position: FancadeW[Vector3], rotation: FancadeW[Rotation]): FancadeW[Unit] = ???
|
||||
override def raycast(from: FancadeW[Vector3], to: FancadeW[Vector3]): FancadeW[Raycast] = ???
|
||||
override def getSize(obj: FancadeW[Obj]): FancadeW[Size] = ???
|
||||
override def setVisible(obj: FancadeW[Obj], visible: FancadeW[Boolean]): FancadeW[Unit] = ???
|
||||
override def createObj(original: FancadeW[Obj]): FancadeW[Obj] = ???
|
||||
override def destroyObj(obj: FancadeW[Obj]): FancadeW[Obj] = ???
|
||||
override def setPosition(obj: Fancade[Obj], position: Fancade[Vector3], rotation: Fancade[Rotation]): Fancade[Unit] = ???
|
||||
override def raycast(from: Fancade[Vector3], to: Fancade[Vector3]): Fancade[Raycast] = ???
|
||||
override def getSize(obj: Fancade[Obj]): Fancade[Size] = ???
|
||||
override def setVisible(obj: Fancade[Obj], visible: Fancade[Boolean]): Fancade[Unit] = ???
|
||||
override def createObj(original: Fancade[Obj]): Fancade[Obj] = ???
|
||||
override def destroyObj(obj: Fancade[Obj]): Fancade[Obj] = ???
|
||||
|
||||
override def playSound(loop: Boolean, sound: Sample)(volume: FancadeW[Float], pitch: FancadeW[Float]): FancadeW[Float] = ???
|
||||
override def stopSound(channel: FancadeW[Float]): FancadeW[Unit] = ???
|
||||
override def volumePitch(channel: FancadeW[Float], volume: FancadeW[Float], pitch: FancadeW[Float]): FancadeW[Unit] = ???
|
||||
override def playSound(loop: Boolean, sound: Sample)(volume: Fancade[Float], pitch: Fancade[Float]): Fancade[Float] = ???
|
||||
override def stopSound(channel: Fancade[Float]): Fancade[Unit] = ???
|
||||
override def volumePitch(channel: Fancade[Float], volume: Fancade[Float], pitch: Fancade[Float]): Fancade[Unit] = ???
|
||||
|
||||
override def addForce(obj: FancadeW[Obj], force: FancadeW[Vector3], applyAt: FancadeW[Vector3], torque: FancadeW[Vector3]): FancadeW[Unit] = ???
|
||||
override def getVelocity(obj: FancadeW[Obj]): FancadeW[Velocity] = ???
|
||||
override def setVelocity(obj: FancadeW[Obj], velocity: FancadeW[Vector3], spin: FancadeW[Vector3]): FancadeW[Unit] = ???
|
||||
override def setLocked(obj: FancadeW[Obj], position: FancadeW[Vector3], rotation: FancadeW[Vector3]): FancadeW[Unit] = ???
|
||||
override def setMass(obj: FancadeW[Obj], mass: FancadeW[Float]): FancadeW[Unit] = ???
|
||||
override def setFriction(obj: FancadeW[Obj], friction: FancadeW[Float]): FancadeW[Unit] = ???
|
||||
override def setBounciness(obj: FancadeW[Obj], bounciness: FancadeW[Float]): FancadeW[Unit] = ???
|
||||
override def setGravity(gravity: FancadeW[Vector3]): FancadeW[Unit] = ???
|
||||
override def addConstraint(base: FancadeW[Obj], part: FancadeW[Obj], pivot: FancadeW[Vector3]): FancadeW[Constraint] = ???
|
||||
override def linearLimits(constraint: FancadeW[Constraint], lower: FancadeW[Vector3], upper: FancadeW[Vector3]): FancadeW[Unit] = ???
|
||||
override def angularLimits(constraint: FancadeW[Constraint], lower: FancadeW[Vector3], upper: FancadeW[Vector3]): FancadeW[Unit] = ???
|
||||
override def linearSpring(constraint: FancadeW[Constraint], stiffness: FancadeW[Vector3], damping: FancadeW[Vector3]): FancadeW[Unit] = ???
|
||||
override def angularSpring(constraint: FancadeW[Constraint], stiffness: FancadeW[Vector3], damping: FancadeW[Vector3]): FancadeW[Unit] = ???
|
||||
override def linearMotor(constraint: FancadeW[Constraint], speed: FancadeW[Vector3], force: FancadeW[Vector3]): FancadeW[Unit] = ???
|
||||
override def angularMotor(constraint: FancadeW[Constraint], speed: FancadeW[Vector3], force: FancadeW[Vector3]): FancadeW[Unit] = ???
|
||||
override def addForce(obj: Fancade[Obj], force: Fancade[Vector3], applyAt: Fancade[Vector3], torque: Fancade[Vector3]): Fancade[Unit] = ???
|
||||
override def getVelocity(obj: Fancade[Obj]): Fancade[Velocity] = ???
|
||||
override def setVelocity(obj: Fancade[Obj], velocity: Fancade[Vector3], spin: Fancade[Vector3]): Fancade[Unit] = ???
|
||||
override def setLocked(obj: Fancade[Obj], position: Fancade[Vector3], rotation: Fancade[Vector3]): Fancade[Unit] = ???
|
||||
override def setMass(obj: Fancade[Obj], mass: Fancade[Float]): Fancade[Unit] = ???
|
||||
override def setFriction(obj: Fancade[Obj], friction: Fancade[Float]): Fancade[Unit] = ???
|
||||
override def setBounciness(obj: Fancade[Obj], bounciness: Fancade[Float]): Fancade[Unit] = ???
|
||||
override def setGravity(gravity: Fancade[Vector3]): Fancade[Unit] = ???
|
||||
override def addConstraint(base: Fancade[Obj], part: Fancade[Obj], pivot: Fancade[Vector3]): Fancade[Constraint] = ???
|
||||
override def linearLimits(constraint: Fancade[Constraint], lower: Fancade[Vector3], upper: Fancade[Vector3]): Fancade[Unit] = ???
|
||||
override def angularLimits(constraint: Fancade[Constraint], lower: Fancade[Vector3], upper: Fancade[Vector3]): Fancade[Unit] = ???
|
||||
override def linearSpring(constraint: Fancade[Constraint], stiffness: Fancade[Vector3], damping: Fancade[Vector3]): Fancade[Unit] = ???
|
||||
override def angularSpring(constraint: Fancade[Constraint], stiffness: Fancade[Vector3], damping: Fancade[Vector3]): Fancade[Unit] = ???
|
||||
override def linearMotor(constraint: Fancade[Constraint], speed: Fancade[Vector3], force: Fancade[Vector3]): Fancade[Unit] = ???
|
||||
override def angularMotor(constraint: Fancade[Constraint], speed: Fancade[Vector3], force: Fancade[Vector3]): Fancade[Unit] = ???
|
||||
|
||||
override def ifElse(cond: FancadeW[Boolean])(ifTrue: FancadeW[Unit])(ifFalse: FancadeW[Unit]): FancadeW[Unit] = ???
|
||||
override def onPlay(onPlay: FancadeW[Unit]): FancadeW[Unit] = ???
|
||||
override def onBoxArt(onBoxArt: FancadeW[Unit]): FancadeW[Unit] = ???
|
||||
override def onTouch(onTouch: FancadeW[Touch] => FancadeW[Unit]): FancadeW[Unit] = ???
|
||||
override def ifElse(cond: Fancade[Boolean])(ifTrue: Fancade[Unit])(ifFalse: Fancade[Unit]): Fancade[Unit] = ???
|
||||
override def onPlay(onPlay: Fancade[Unit]): Fancade[Unit] = ???
|
||||
override def onBoxArt(onBoxArt: Fancade[Unit]): Fancade[Unit] = ???
|
||||
override def onTouch(onTouch: Fancade[Touch] => Fancade[Unit]): Fancade[Unit] = ???
|
||||
|
||||
override def addNumbers(a: Fancade[Float], b: Fancade[Float]): Fancade[Float] =
|
||||
Fix(FancadeF.Use(
|
||||
Vector(a, b),
|
||||
Exists(Template(
|
||||
BlockDefinition.AddNumbers,
|
||||
()
|
||||
)),
|
||||
Vector(BlockDefinition.AddNumbers.input1, BlockDefinition.AddNumbers.input2),
|
||||
Vector(BlockDefinition.AddNumbers.output)
|
||||
))
|
||||
|
||||
override def screenSizeWidth(screenSize: FancadeW[ScreenSize]): FancadeW[Float] = ???
|
||||
override def screenSizeHeight(screenSize: FancadeW[ScreenSize]): FancadeW[Float] = ???
|
||||
override def screenSizeWidth(screenSize: Fancade[ScreenSize]): Fancade[Float] = ???
|
||||
override def screenSizeHeight(screenSize: Fancade[ScreenSize]): Fancade[Float] = ???
|
||||
|
||||
override def positionPosition(position: FancadeW[Position]): FancadeW[Vector3] = ???
|
||||
override def positionRotation(position: FancadeW[Position]): FancadeW[Rotation] = ???
|
||||
override def positionPosition(position: Fancade[Position]): Fancade[Vector3] = ???
|
||||
override def positionRotation(position: Fancade[Position]): Fancade[Rotation] = ???
|
||||
|
||||
override def raycastHit(raycast: FancadeW[Raycast]): FancadeW[Boolean] = ???
|
||||
override def raycastPosition(raycast: FancadeW[Raycast]): FancadeW[Vector3] = ???
|
||||
override def raycastObj(raycast: FancadeW[Raycast]): FancadeW[Obj] = ???
|
||||
override def raycastHit(raycast: Fancade[Raycast]): Fancade[Boolean] = ???
|
||||
override def raycastPosition(raycast: Fancade[Raycast]): Fancade[Vector3] = ???
|
||||
override def raycastObj(raycast: Fancade[Raycast]): Fancade[Obj] = ???
|
||||
|
||||
override def sizeMin(size: FancadeW[Size]): FancadeW[Vector3] = ???
|
||||
override def sizeMax(size: FancadeW[Size]): FancadeW[Vector3] = ???
|
||||
override def sizeMin(size: Fancade[Size]): Fancade[Vector3] = ???
|
||||
override def sizeMax(size: Fancade[Size]): Fancade[Vector3] = ???
|
||||
|
||||
override def velocityVelocity(velocity: FancadeW[Velocity]): FancadeW[Vector3] = ???
|
||||
override def velocitySpin(velocity: FancadeW[Velocity]): FancadeW[Vector3] = ???
|
||||
override def velocityVelocity(velocity: Fancade[Velocity]): Fancade[Vector3] = ???
|
||||
override def velocitySpin(velocity: Fancade[Velocity]): Fancade[Vector3] = ???
|
||||
|
||||
}
|
||||
|
||||
|
|
62
tagless/src/main/scala/tf/bug/fancadetagless/Main.scala
Normal file
62
tagless/src/main/scala/tf/bug/fancadetagless/Main.scala
Normal file
|
@ -0,0 +1,62 @@
|
|||
package tf.bug.fancadetagless
|
||||
|
||||
import cats.effect.{Blocker, ContextShift, ExitCode, IO, IOApp, Sync}
|
||||
import fs2._
|
||||
import higherkindness.droste.data._
|
||||
import java.nio.file.{Paths, StandardOpenOption}
|
||||
import scodec.stream.StreamEncoder
|
||||
import tf.bug.fancadegraph.Level
|
||||
import tf.bug.fancadescodec.Cartridge
|
||||
import tf.bug.fancadescodec.Codecs
|
||||
|
||||
object Main extends IOApp {
|
||||
|
||||
override def run(args: List[String]): IO[ExitCode] =
|
||||
program[IO].compile.drain.as(ExitCode.Success)
|
||||
|
||||
def program[F[_] : Sync : ContextShift]: Stream[F, Unit] = {
|
||||
val program = new Fanscript.Program[Float] {
|
||||
override def run[G[_]](implicit interp: Fanscript[G]): G[Float] = {
|
||||
val one = interp.lift(1.0f)
|
||||
val two = interp.lift(2.0f)
|
||||
val three = interp.lift(3.0f)
|
||||
interp.addNumbers(
|
||||
interp.addNumbers(
|
||||
one,
|
||||
interp.addNumbers(
|
||||
two,
|
||||
three
|
||||
)
|
||||
),
|
||||
interp.addNumbers(
|
||||
two,
|
||||
three
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val fancade: Fix[FancadeF] = program.run[Fancade]
|
||||
|
||||
val level: Level = FancadeF.render(fancade)
|
||||
|
||||
val cart: Cartridge = Cartridge(
|
||||
"Test",
|
||||
"rayc",
|
||||
"Test of tagless",
|
||||
Vector(
|
||||
Level.encode(level)
|
||||
)
|
||||
)
|
||||
|
||||
val output = Paths.get("""C:\Users\aprim\Documents\FancadeLevels\TaglessTest""")
|
||||
|
||||
(for {
|
||||
blocker <- Stream.resource(Blocker[F])
|
||||
result <- Stream.emit[F, Cartridge](cart)
|
||||
.through(StreamEncoder.once(Codecs.encCartridge).toPipeByte[F])
|
||||
.through(io.file.writeAll(output, blocker, Seq(StandardOpenOption.TRUNCATE_EXISTING)))
|
||||
} yield result)
|
||||
}
|
||||
|
||||
}
|
|
@ -2,21 +2,51 @@ package tf.bug.fancadetagless
|
|||
|
||||
import cats._
|
||||
import cats.implicits._
|
||||
import cats.data.State
|
||||
import higherkindness.droste._
|
||||
import higherkindness.droste.data._
|
||||
import higherkindness.droste.scheme
|
||||
|
||||
case class PointerChain[F[_]](internal: Map[Int, F[Int]])(implicit functor: Functor[F]) {
|
||||
case class PointerChain[T[_], E[_]](vertices: Vector[E[Int]], roots: T[Int])
|
||||
|
||||
def ++(other: PointerChain[F]): PointerChain[F] = {
|
||||
???
|
||||
}
|
||||
|
||||
def map[B](f: ((Int, F[Int])) => B): Vector[B] = internal.map(f).toVector
|
||||
|
||||
}
|
||||
case class PointerState[F[_]](seen: Map[F[Int], Int], vertices: Vector[F[Int]], lastIndex: Int)
|
||||
|
||||
object PointerChain {
|
||||
|
||||
def empty[F[_] : Functor]: PointerChain[F] = PointerChain(Map.empty)
|
||||
def deduplicate[R[_], F[_]](input: R[Fix[F]])(
|
||||
implicit rt: Traverse[R],
|
||||
rf: Traverse[F]
|
||||
): PointerChain[R, F] = {
|
||||
val addAll: State[PointerState[F], R[Int]] = input.traverse(scheme.cataM(findOrAddNode[F]))
|
||||
val result: (PointerState[F], R[Int]) = addAll.run(PointerState.empty[F]).value
|
||||
val graphed: (Vector[F[Int]], R[Int]) = result.leftMap(_.vertices.reverse)
|
||||
val chain: PointerChain[R, F] = PointerChain(graphed._1, graphed._2)
|
||||
chain
|
||||
}
|
||||
|
||||
def single[F[_] : Functor](value: F[Nothing]): PointerChain[F] = PointerChain(Map(0 -> value.widen))
|
||||
def findOrAddNode[F[_]]: AlgebraM[State[PointerState[F], *], F, Int] = AlgebraM { tree =>
|
||||
for {
|
||||
gs <- State.get[PointerState[F]]
|
||||
seen = gs.seen
|
||||
result <- seen.get(tree) match {
|
||||
case Some(index) => State.pure[PointerState[F], Int](index)
|
||||
case None =>
|
||||
val index = gs.lastIndex
|
||||
for {
|
||||
_ <- State.set(PointerState(
|
||||
seen + (tree -> index),
|
||||
tree +: gs.vertices,
|
||||
index + 1
|
||||
))
|
||||
} yield index
|
||||
}
|
||||
} yield result
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
object PointerState {
|
||||
|
||||
def empty[F[_]]: PointerState[F] = PointerState(Map(), Vector(), 0)
|
||||
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import higherkindness.droste.data.Fix
|
|||
|
||||
package object fancadetagless {
|
||||
|
||||
type FancadeF = Fix[Fancade]
|
||||
type FancadeW[A] = FancadeF
|
||||
type Fancade[A] = Fix[FancadeF]
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue