Skip to content

Commit

Permalink
Merge pull request #27 from julianpeeters/dev
Browse files Browse the repository at this point in the history
Add basic monomial Cartesian products
  • Loading branch information
julianpeeters committed Mar 23, 2024
2 parents 1999b7f + ef2eadc commit b324c01
Show file tree
Hide file tree
Showing 11 changed files with 229 additions and 49 deletions.
25 changes: 16 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ Based on the polynomial functors described in [Niu and Spivak](https://topos.sit
---

### Add the dependencies:
- libraries for Scala 3 (JS, JVM, and Native platforms)
- libraries for Scala 3.4+ (JS, JVM, and Native platforms)
- mermaid integration (optional)

```scala
"com.julianpeeters" %% "polynomial" % "0.5.0"
"com.julianpeeters" %% "polynomial-mermaid" % "0.5.0"
"com.julianpeeters" %% "polynomial" % "0.6.0" // required
"com.julianpeeters" %% "polynomial-mermaid" % "0.6.0" // optional
```

---
Expand All @@ -21,14 +21,15 @@ The `polynomial` library provides the following implementation of poly:
- objects: built-in ADTs for monomial, binomial, and trinomial `Store` and `Interface` functors
- morphisms: `PolyMap`, or `~>`, a natural transformation between polynomial functors
- products:
- `Composition`, or ``, a composition product implemented as match types
- `Cartesian`, or `×`, a categorical product implemented as match types
- `Composition`, or ``, a substitution product implemented as match types
- `Tensor`, or ``, a parallel product implemented as match types

```scala
import polynomial.`object`.*
import polynomial.morphism.~>

// Example types:
// Examples
type `2y⁵¹²` = Monomial.Interface[(Byte, Boolean), Boolean, _]
type `y² + 2y` = Binomial.BiInterface[Boolean, Unit, Unit, Boolean, _]
type `2y²` = Monomial.Store[Boolean, _]
Expand Down Expand Up @@ -65,19 +66,25 @@ be printed, with titles and labels in the following formats:


```scala
import polynomial.`object`.Monomial.{Interface, Store}
import polynomial.`object`.Monomial.{Interface}
import polynomial.mermaid.{Format, Mermaid, given}
import polynomial.morphism.~>

type F[Y] = (Store[Boolean, _] ~> Interface[Byte, Char, _])[Y]
type F[Y] = (Interface[Byte, Char, _] ~> Interface[Byte, Char, _])[Y]

val M: Mermaid[F] = summon[Mermaid[F]]
// M: Mermaid[F] = polynomial.mermaid.Mermaid$$anon$1@3fc89d02
// M: Mermaid[F] = polynomial.mermaid.Mermaid$$anon$3@49cbc7e8

println(M.showGraph(graphFmt = Format.Generic))
// ```mermaid
// graph LR;
// A:::hidden---|<span style="font-family:Courier">A</span>|S[<span style="font-family:Courier">S</span>]---|<span style="font-family:Courier">B</span>|B:::hidden;
// A1:::hidden---|<span style="font-family:Courier">A<sub>2</sub></span>|A_B1[ ]:::point
// subgraph s[ ]
// A_B1:::point---QB1
// QB1[<span style="font-family:Courier">B<sub>1</sub></span>𝑦<sup><span style="font-family:Courier">A<sub>1</sub></span></sup>]:::empty
// QB1---B_B1
// end
// B_B1[ ]:::point---|<span style="font-family:Courier">B<sub>2</sub></span>|B1:::hidden;
//
// classDef empty fill:background;
// classDef point width:0px, height:0px;
Expand Down
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ lazy val docs = project.in(file("docs/gitignored"))
.settings(
mdocOut := file("."),
mdocVariables := Map(
"SCALA" -> crossScalaVersions.value.map(e => e.takeWhile(_ != '.')).mkString(", "),
"SCALA" -> crossScalaVersions.value.map(e => e.reverse.dropWhile(_ != '.').drop(1).reverse + "+").mkString(", "),
"VERSION" -> version.value.takeWhile(_ != '+'),
)
)
Expand Down
13 changes: 7 additions & 6 deletions docs/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ Based on the polynomial functors described in [Niu and Spivak](https://topos.sit
- mermaid integration (optional)

```scala
"com.julianpeeters" %% "polynomial" % "@VERSION@"
"com.julianpeeters" %% "polynomial-mermaid" % "@VERSION@"
"com.julianpeeters" %% "polynomial" % "@VERSION@" // required
"com.julianpeeters" %% "polynomial-mermaid" % "@VERSION@" // optional
```

---
Expand All @@ -21,14 +21,15 @@ The `polynomial` library provides the following implementation of poly:
- objects: built-in ADTs for monomial, binomial, and trinomial `Store` and `Interface` functors
- morphisms: `PolyMap`, or `~>`, a natural transformation between polynomial functors
- products:
- `Composition`, or ``, a composition product implemented as match types
- `Cartesian`, or `×`, a categorical product implemented as match types
- `Composition`, or ``, a substitution product implemented as match types
- `Tensor`, or ``, a parallel product implemented as match types

```scala mdoc
import polynomial.`object`.*
import polynomial.morphism.~>

// Example types:
// Examples
type `2y⁵¹²` = Monomial.Interface[(Byte, Boolean), Boolean, _]
type `y² + 2y` = Binomial.BiInterface[Boolean, Unit, Unit, Boolean, _]
type `2y²` = Monomial.Store[Boolean, _]
Expand Down Expand Up @@ -65,11 +66,11 @@ be printed, with titles and labels in the following formats:


```scala mdoc:reset
import polynomial.`object`.Monomial.{Interface, Store}
import polynomial.`object`.Monomial.{Interface}
import polynomial.mermaid.{Format, Mermaid, given}
import polynomial.morphism.~>

type F[Y] = (Store[Boolean, _] ~> Interface[Byte, Char, _])[Y]
type F[Y] = (Interface[Byte, Char, _] ~> Interface[Byte, Char, _])[Y]

val M: Mermaid[F] = summon[Mermaid[F]]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import polynomial.mermaid.render.{Render, addTitle}
import polynomial.morphism.PolyMap
import polynomial.`object`.Binomial.BiInterface
import polynomial.`object`.Monomial.{Interface, Store}
import polynomial.product.{Tensor, }
import polynomial.product.{Cartesian, Tensor, }

trait Mermaid[F[_]]:
def showGraph(graphFmt: Format): String
Expand All @@ -17,8 +17,8 @@ trait Mermaid[F[_]]:
def showTitleCustom[Y](labels: CustomLabels[F[Y]]): String
def showTitleHtml(titleFmt: Format): String
def showTitleHtmlCustom[Y](labels: CustomLabels[F[Y]]): String
def showTitledGraph(titleFmt: Format, graphFmt: Format): String
def showTitledGraphCustom[Y](graphFmt: Format, labels: CustomLabels[F[Y]]): String
// def showTitledGraph(titleFmt: Format, graphFmt: Format): String
// def showTitledGraphCustom[Y](graphFmt: Format, labels: CustomLabels[F[Y]]): String

object Mermaid:

Expand All @@ -30,6 +30,7 @@ object Mermaid:
case (Store[s1, y1], Store[s2, y2]) => (String, String)
case (Tensor[o, p, y1], Interface[q, r, y2]) => (CustomLabels[(o[y1], p[y1])], String)
case (Tensor[o, p, y1], Tensor[q, r, y2]) => (CustomLabels[(o[y1], p[y1])], CustomLabels[(q[y2], r[y2])])
case (Cartesian[o, p, y1], Cartesian[q, r, y2]) => (CustomLabels[(o[y1], p[y1])], CustomLabels[(q[y2], r[y2])])

type ParamLabels[X] = X match
case Interface[a, b, y] => (String, String)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package polynomial.mermaid.instances

import polynomial.mermaid.Mermaid
import polynomial.mermaid.render.p.MermaidP
import polynomial.mermaid.render.q.MermaidQ
import polynomial.mermaid.render.Format.{Cardinal, Generic, Specific}
import polynomial.mermaid.render.Format
import polynomial.mermaid.render.Render
import polynomial.morphism.PolyMap
import polynomial.`object`.Monomial.{Interface, Store}
import polynomial.product.×

given mooreTensoredStoreToTensoredMonomial[S1, S2, A1, B1, A2, B2](using
P1: MermaidP[Store[S1, _]],
P2: MermaidP[Store[S2, _]],
Q1: MermaidQ[Interface[A1, B1, _]],
Q2: MermaidQ[Interface[A2, B2, _]],
): Mermaid[PolyMap[Store[S1, _] × Store[S2, _], Interface[A1, B1, _] × Interface[A2, B2, _], _]] =
new Mermaid[PolyMap[Store[S1, _] × Store[S2, _], Interface[A1, B1, _] × Interface[A2, B2, _], _]]:
private val labelS1 = "S<sub>1</sub>"
private val labelS2 = "S<sub>2</sub>"
private val labelA1 = "A<sub>1</sub>"
private val labelA2 = "A<sub>2</sub>"
private val labelB1 = "B<sub>1</sub>"
private val labelB2 = "B<sub>2</sub>"
private val nodeS1 = "S1"
private val nodeS2 = "S2"
private val nodeA1 = "A1:::hidden"
private val nodeA2 = "A2:::hidden"
private val nodeB1 = "B1:::hidden"
private val nodeB2 = "B2:::hidden"

// private val nodeA = "A<sub>1</sub>∨A<sub>2</sub>"

def showGraph(graphFmt: Format): String =
graphFmt match
case Cardinal =>
Render.mermaidCodeFence(Render.tensored(Q1.graphQCardinal((nodeA1, nodeB1))(P1.graphPCardinal(nodeS1, P1.polynomialCardinal)), Q2.graphQCardinal((nodeA2, nodeB2))(P2.graphPCardinal(nodeS2, P2.polynomialCardinal))))
case Generic =>
Render.mermaidCodeFence(Render.tensored(Q1.graphQGeneric((nodeA1, nodeB1), (labelA1, labelB1))(P1.graphPGeneric(nodeS1, P1.polynomialGeneric(labelS1), labelS1)), Q2.graphQGeneric((nodeA2, nodeB2), (labelA2, labelB2))(P2.graphPGeneric(nodeS2, P2.polynomialGeneric(labelS2), labelS2))))
case Specific =>
Render.mermaidCodeFence(Render.tensored(Q1.graphQSpecific((nodeA1, nodeB1))(P1.graphPSpecific(nodeS1, P1.polynomialSpecific)), Q2.graphQSpecific((nodeA2, nodeB2))(P2.graphPSpecific(nodeS2, P2.polynomialSpecific))))
def showGraphCustom[Y](graphFmt: Format, labels: ((String, String), (String, String))): String =
???
def showTitle(titleFmt: Format): String =
???
def showTitleCustom[Y](labels: ((String, String), (String, String))): String =
???
def showTitleHtml(titleFmt: Format): String =
???
def showTitleHtmlCustom[Y](labels: ((String, String), (String, String))): String =
???
// def showTitledGraph(titleFmt: Format, graphFmt: Format): String =
// graphFmt match
// case Cardinal =>
// Render.mermaidCodeFence(Render.tensored(Q1.graphQCardinal((nodeA1, nodeB1))(P1.graphPCardinal(nodeS1, P1.polynomialCardinal)), Q2.graphQCardinal((nodeA2, nodeB2))(P2.graphPCardinal(nodeS2, P2.polynomialCardinal))))
// .addTitle(Render.tensor(P1.polynomialCardinal, P2.polynomialCardinal), 3, Render.tensor(Q1.polynomialCardinal, Q2.polynomialCardinal), 3)
// case Generic =>
// Render.mermaidCodeFence(Render.tensored(Q1.graphQGeneric((nodeA1, nodeB1), (labelA1, labelB1))(P1.graphPGeneric(nodeS1, P1.polynomialGeneric(labelS1), labelS1)), Q2.graphQGeneric((nodeA2, nodeB2), (labelA2, labelB2))(P2.graphPGeneric(nodeS2, P2.polynomialGeneric(labelS2), labelS2))))
// .addTitle(Render.tensor(P1.polynomialGeneric(labelS1), P2.polynomialGeneric(labelS2)), 3, Render.tensor(Q1.polynomialGeneric((labelA1, labelB1)), Q2.polynomialGeneric((labelA2, labelB2))), 3)
// case Specific =>
// Render.mermaidCodeFence(Render.tensored(Q1.graphQSpecific((nodeA1, nodeB1))(P1.graphPSpecific(nodeS1, P1.polynomialSpecific)), Q2.graphQSpecific((nodeA2, nodeB2))(P2.graphPSpecific(nodeS2, P2.polynomialSpecific))))
// .addTitle(Render.tensor(P1.polynomialSpecific, P2.polynomialSpecific), 3, Render.tensor(Q1.polynomialSpecific, Q2.polynomialSpecific), 3)
// def showTitledGraphCustom[Y](graphFmt: Format, labels: ((String, String), (String, String))): String =
// ???
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ package polynomial.morphism

import cats.Id
import polynomial.`object`.Binomial.BiInterface
import polynomial.`object`.Monomial.{Interface, Store}
import polynomial.product.{Tensor, Composition}
import polynomial.`object`.Monomial.{Interface, Store, StoreF}
import polynomial.product.{Cartesian, Composition, Tensor}

type ~>[P[_], Q[_]] = PolyMap[P, Q, _]

Expand All @@ -13,13 +13,6 @@ abstract class PolyMap[P[_], Q[_], Y]:

object PolyMap:

export polynomial.morphism.methods.andThen.mS_bI.*
export polynomial.morphism.methods.andThen.mS_mI.*
export polynomial.morphism.methods.andThen.mSTensormS_bITensorbI.*
export polynomial.morphism.methods.andThen.mSTensormS_mITensormI.*
export polynomial.morphism.methods.andThen.mSTensormSTensorms_mITensormITensormI.*
export polynomial.morphism.methods.swap.*

def apply[P[_], Q[_], Y](
phi: Phi[P, Q, Y],
phiSharp: PhiSharp[P, Q, Y]
Expand All @@ -28,7 +21,7 @@ object PolyMap:
def φ: Phi[P, Q, Y] = phi
def `φ#`: PhiSharp[P, Q, Y] = phiSharp

type Phi[P[_], Q[_], Y] = (P[Y], Q[Y]) match
type Phi[P[_], Q[_], Y] = (Eval[P, Y], Eval[Q, Y]) match
case (BiInterface[a1, b1, a2, b2, Y], BiInterface[a3, b3, a4, b4, Y]) => (b1 => b3, b2 => b4)
case (BiInterface[a1, b1, a2, b2, Y], Interface[a3, b3, Y]) => (b1 => b3, b2 => b3)
case (Interface[a1, b1, Y], BiInterface[a3, b3, a4, b4, Y]) => (b1 => b3, b1 => b4)
Expand All @@ -38,24 +31,35 @@ object PolyMap:
case (PolyMap[o, p, Y], Tensor[q, r, Y]) => Phi[o, Tensor[q, r, _], Y]
case (Store[s, Y], BiInterface[a1, b1, a2, b2, Y]) => (s => b1, s => b2)
case (Store[s, Y], Interface[a, b, Y]) => s => b
case (StoreF[f, s, Y], Interface[a, b, Y]) => s => b
case (Store[s, Y], Composition[p, q, Y]) => (Phi[Store[s, _], p, Y], Phi[p, q, Y])
case (Tensor[p, q, Y], Store[s1, Y]) => Phi[Tensor.DayConvolution[p, q, _], Store[s1, _], Y]
case (Tensor[p, q, Y], Interface[a1, b1, Y]) => Phi[Tensor.DayConvolution[p, q, _], Interface[a1, b1, _], Y]
case (Tensor[p, q, Y], BiInterface[a1, b1, a2, b2, Y]) => Phi[Tensor.DayConvolution[p, q, _], BiInterface[a1, b1, a2, b2, _], Y]
case (Tensor[o, p, Y], Tensor[q, r, Y]) => Phi[Tensor.DayConvolution[o, p, _], Tensor.DayConvolution[q, r, _], Y]

type PhiSharp[P[_], Q[_], Y] = (P[Y], Q[Y]) match
type PhiSharp[P[_], Q[_], Y] = (Eval[P, Y], Eval[Q, Y]) match
case (BiInterface[a1, b1, a2, b2, Y], BiInterface[a3, b3, a4, b4, Y]) => ((b1, a3) => a1, (b2, a4) => a2)
case (BiInterface[a1, b1, a2, b2, Y], Interface[a3, b3, Y]) => ((b1, a3) => a1, (b2, a3) => a2)
case (Interface[a1, b1, Y], BiInterface[a2, b2, a3, b3, Y]) => ((b1, a2) => a1, (b1, a3) => a1)
case (Interface[a1, b1, Y], Interface[a2, b2, Y]) => (b1, a2) => a1
case (Store[s, Y], BiInterface[a1, b1, a2, b2, Y]) => ((s, a1) => s, (s, a2) => s)
case (Store[s, Y], Interface[a, b, Y]) => (s, a) => s
case (StoreF[f, s, Y], Interface[a, b, Y]) => (s, a) => f[s]
case (Store[s, Y], Composition[p, q, Y]) => (s, Composition.DecomposeSharp[p, q, Y]) => s
case (PolyMap[p, q, Y], BiInterface[a3, b3, a4, b4, Y]) => PhiSharp[p, BiInterface[a3, b3, a4, b4, _], Y]
case (PolyMap[p, q, Y], Interface[a2, b2, Y]) => PhiSharp[p, Interface[a2, b2, _], Y]
case (PolyMap[o, p, Y], Tensor[q, r, Y]) => PhiSharp[o, Tensor[q, r, _], Y]
case (Tensor[p, q, Y], BiInterface[a1, b1, a2, b2, Y]) => PhiSharp[Tensor.DayConvolution[p, q, _], BiInterface[a1, b1, a2, b2, _], Y]
case (Tensor[p, q, Y], Interface[a1, b1, Y]) => PhiSharp[Tensor.DayConvolution[p, q, _], Interface[a1, b1, _], Y]
case (Tensor[p, q, Y], Store[s1, Y]) => PhiSharp[Tensor.DayConvolution[p, q, _], Store[s1, _], Y]
case (Tensor[o, p, Y], Tensor[q, r, Y]) => PhiSharp[Tensor.DayConvolution[o, p, _], Tensor.DayConvolution[q, r, _], Y]

type Eval[P[_], Y] = P[Y] match
case BiInterface[a1, b1, a2, b2, Y] => BiInterface[a1, b1, a2, b2, Y]
case Cartesian[p, q, Y] => Cartesian.And[Eval[p, _], Eval[q, _], Y]
case Composition[p, q, Y] => Composition[p, q, Y]
case Interface[a, b, Y] => Interface[a, b, Y]
case PolyMap[p, q, Y] => PolyMap[p, q, Y]
case Store[s, Y] => Store[s, Y]
case StoreF[f, s, Y] => StoreF[f, s, Y]
case Tensor[p, q, Y] => Tensor.DayConvolution[Eval[p, _], Eval[q, _], Y]

export polynomial.morphism.methods.andThen.mS_bI.*
export polynomial.morphism.methods.andThen.mS_mI.*
export polynomial.morphism.methods.andThen.mS_mICartesianmI.*
export polynomial.morphism.methods.andThen.mSTensormS_bITensorbI.*
export polynomial.morphism.methods.andThen.mSTensormS_mITensormI.*
export polynomial.morphism.methods.andThen.mSTensormSTensorms_mITensormITensormI.*
export polynomial.morphism.methods.swap.*
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ package polynomial.morphism.methods.andThen

import cats.Id
import polynomial.morphism.PolyMap
import polynomial.`object`.Monomial.{Interface, Store}
import polynomial.`object`.Monomial.{Interface, Store, StoreF}
import cats.{FlatMap, Monad}

object mS_mI:

Expand All @@ -17,13 +18,35 @@ object mS_mI:
def `φ#`: PolyMap.PhiSharp[PolyMap[Store[Id[S], _], Interface[Id[A1], Id[B1], _], _], Interface[Id[A2], Id[B2], _], Y] =
(s, a) => p.`φ#`(s, w.`φ#`(p.φ(s), a))

extension [S, A1, B1, Y] (p: PolyMap[Store[Option[S], _], Interface[A1, Option[B1], _], Y])
@scala.annotation.targetName("andThenStoreMonoToMonoOptionPrism")
extension [F[_]: FlatMap, S, A, B, Y] (p: PolyMap[Store[F[S], _], Interface[A, F[B], _], Y])
@scala.annotation.targetName("andThenStoreMonoToMonoFPrism")
def andThen(
w: PolyMap[Interface[A1, Id[B1], _], Interface[A1, A1 => Option[B1], _], Y]
): PolyMap[PolyMap[Store[Option[S], _], Interface[A1, Id[B1], _], _], Interface[A1, A1 => Option[B1], _], Y] =
new PolyMap[PolyMap[Store[Option[S], _], Interface[A1, Id[B1], _], _], Interface[A1, A1 => Option[B1], _], Y]:
def φ: PolyMap.Phi[PolyMap[Store[Option[S], _], Interface[A1, Id[B1], _], _], Interface[A1, A1 => Option[B1], _], Y] =
s => a2 => p.φ(s).flatMap(b1 => w.φ(b1)(a2))
def `φ#`: PolyMap.PhiSharp[PolyMap[Store[Option[S], _], Interface[A1, Id[B1], _], _], Interface[A1, A1 => Option[B1], _], Y] =
(s, a) => p.φ(s).flatMap(b1 => p.`φ#`(s, w.`φ#`(b1, a)))
w: PolyMap[Interface[A, Id[B], _], Interface[A, A => F[B], _], Y]
): PolyMap[PolyMap[Store[F[S], _], Interface[A, Id[B], _], _], Interface[A, A => F[B], _], Y] =
new PolyMap[PolyMap[Store[F[S], _], Interface[A, Id[B], _], _], Interface[A, A => F[B], _], Y]:
def φ: PolyMap.Phi[PolyMap[Store[F[S], _], Interface[A, Id[B], _], _], Interface[A, A => F[B], _], Y] =
s => a2 => FlatMap[F].flatMap(p.φ(s))(b1 => w.φ(b1)(a2))
def `φ#`: PolyMap.PhiSharp[PolyMap[Store[F[S], _], Interface[A, Id[B], _], _], Interface[A, A => F[B], _], Y] =
(s, a) => FlatMap[F].flatMap(p.φ(s))(b1 => p.`φ#`(s, w.`φ#`(b1, a)))

extension [F[_]: Monad, S, A, B, Y] (p: PolyMap[StoreF[F, S, _], Interface[A, F[B], _], Y])
@scala.annotation.targetName("andThenStoreFMonoToMonoFPrism")
def andThen(
w: PolyMap[Interface[A, F[B], _], Interface[A, A => F[B], _], Y]
): PolyMap[PolyMap[StoreF[F, S, _], Interface[A, F[B], _], _], Interface[A, A => F[B], _], Y] =
new PolyMap[PolyMap[StoreF[F, S, _], Interface[A, F[B], _], _], Interface[A, A => F[B], _], Y]:
def φ: PolyMap.Phi[PolyMap[StoreF[F, S, _], Interface[A, F[B], _], _], Interface[A, A => F[B], _], Y] =
s => a2 => Monad[F].flatMap(p.φ(s))(b1 => w.φ(Monad[F].pure(b1))(a2))
def `φ#`: PolyMap.PhiSharp[PolyMap[StoreF[F, S, _], Interface[A, F[B], _], _], Interface[A, A => F[B], _], Y] =
(s, a) => Monad[F].flatMap(p.φ(s))(b1 => p.`φ#`(s, w.`φ#`(Monad[F].pure(b1), a)))

extension [F[_]: Monad, S, A, B, Y] (p: PolyMap[Interface[F[S], S, _], Interface[A, F[B], _], Y])
@scala.annotation.targetName("andThenFStoreMonoToMonoFPrism")
def andThen(
w: PolyMap[Interface[A, F[B], _], Interface[A, A => F[B], _], Y]
): PolyMap[PolyMap[Interface[F[S], S, _], Interface[A, F[B], _], _], Interface[A, A => F[B], _], Y] =
new PolyMap[PolyMap[Interface[F[S], S, _], Interface[A, F[B], _], _], Interface[A, A => F[B], _], Y]:
def φ: PolyMap.Phi[PolyMap[Interface[F[S], S, _], Interface[A, F[B], _], _], Interface[A, A => F[B], _], Y] =
s => a2 => Monad[F].flatMap(p.φ(s))(b1 => w.φ(Monad[F].pure(b1))(a2))
def `φ#`: PolyMap.PhiSharp[PolyMap[Interface[F[S], S, _], Interface[A, F[B], _], _], Interface[A, A => F[B], _], Y] =
(s, a) => Monad[F].flatMap(p.φ(s))(b1 => p.`φ#`(s, w.`φ#`(Monad[F].pure(b1), a)))

0 comments on commit b324c01

Please sign in to comment.