package tf.bug.fancadetagless.test import cats.effect.Sync import tf.bug.fancadetagless.{FancadeT, Make, PinDirection, PinType, Pins} trait Calc[W[_]] { def lift(f: Float): W[Float] def add(a: W[Float], b: W[Float]): W[Float] def sub(a: W[Float], b: W[Float]): W[Float] def mul(a: W[Float], b: W[Float]): W[Float] def div(a: W[Float], b: W[Float]): W[Float] } object Calc { trait Program[R] { def apply[F[_]](int: Calc[F]): F[R] } case class FancadeCalc[F[_]]()(implicit s: Sync[F]) extends Calc[FancadeT[F, *]] { override def lift(f: Float): FancadeT[F, Float] = FancadeT.constant(f) override def add(a: FancadeT[F, Float], b: FancadeT[F, Float]): FancadeT[F, Float] = for { addBlock <- FancadeT.make(Make.Builtin("Add[Number]", Vector( (PinType.Number, PinDirection.Inward), (PinType.Number, PinDirection.Inward), (PinType.Number, PinDirection.Outward) ))) ab <- a bb <- b _ <- FancadeT.connect(ab.pins.head, addBlock.pins(0)) _ <- FancadeT.connect(bb.pins.head, addBlock.pins(1)) } yield Pins(addBlock.pins.drop(2)) override def sub(a: FancadeT[F, Float], b: FancadeT[F, Float]): FancadeT[F, Float] = ??? override def mul(a: FancadeT[F, Float], b: FancadeT[F, Float]): FancadeT[F, Float] = ??? override def div(a: FancadeT[F, Float], b: FancadeT[F, Float]): FancadeT[F, Float] = for { addBlock <- FancadeT.make(Make.Builtin("Divide[Number]", Vector( (PinType.Number, PinDirection.Inward), (PinType.Number, PinDirection.Inward), (PinType.Number, PinDirection.Outward) ))) ab <- a bb <- b _ <- FancadeT.connect(ab.pins.head, addBlock.pins(0)) _ <- FancadeT.connect(bb.pins.head, addBlock.pins(1)) } yield Pins(addBlock.pins.drop(2)) } }