All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
chuchortdev.hkd4s_3.1.0.0.source-code.HkdUtils.scala Maven / Gradle / Ivy
package com.tschuchort.hkd
import cats.data.Const
import com.tschuchort.hkd.internal.{ArrayProduct, `*`, `.`}
import shapeless3.deriving.{K11, summonAsArray}
import scala.deriving.Mirror
/** Summon [[HkdFieldInstances]] to summon instances for every possible field of a higher-kinded data type [[D]]. */
trait HkdFieldInstances[D[_[_]], F[_], I[_]] {
def zip[G[_]](df: D[G]): D[[A] =>> (G[A], I[F[A]])]
def instancesFor[G[_]](d: D[G])(using FunctorK[D]): D[I `.` F] =
zip[G](d).mapK[I `.` F]([A] => (fieldAndInstance: (G[A], I[F[A]])) => fieldAndInstance._2)
}
object HkdFieldInstances {
class OfProduct[D[_[_]], F[_], I[_]](private val fieldInstances: D[I `.` F])(using
m: Mirror.Product { type MirroredType[G[_]] = D[G]; type MirroredElemTypes[G[_]] <: Tuple }
) extends HkdFieldInstances[D, F, I] {
override def zip[G[_]](df: D[G]): D[[A] =>> (G[A], I[F[A]])] = {
val fieldsArr = Tuple.fromProduct(df.asInstanceOf[Product]).toArray
val instancesArr = Tuple.fromProduct(fieldInstances.asInstanceOf[Product]).toArray
m.fromProduct(ArrayProduct(fieldsArr.zip(instancesArr).asInstanceOf[Array[Any]])).asInstanceOf[D[G * (I `.` F)]]
}
}
class OfSum[D[_[_]], F[_], I[_]](private val casesInstances: Array[HkdFieldInstances[D, F, I]])(using
m: Mirror.Sum { type MirroredType[G[_]] = D[G]; type MirroredElemTypes[G[_]] <: Tuple }
) extends HkdFieldInstances[D, F, I] {
override def zip[G[_]](df: D[G]): D[[A] =>> (G[A], I[F[A]])] = {
casesInstances(m.ordinal(df.asInstanceOf[m.MirroredMonoType])).zip(df)
}
}
inline given [D[_[_]], F[_], I[_]](using
m: Mirror.Product { type MirroredType[G[_]] = D[G]; type MirroredElemTypes[G[_]] <: Tuple }
): HkdFieldInstances.OfProduct[D, F, I] =
HkdFieldInstances.OfProduct(
m.fromProduct(ArrayProduct(summonAsArray[m.MirroredElemTypes[I `.` F]])).asInstanceOf[D[I `.` F]]
)
inline given [D[_[_]], F[_], I[_]](using
m: Mirror.Sum { type MirroredType[G[_]] = D[G]; type MirroredElemTypes[G[_]] <: Tuple }
): HkdFieldInstances.OfSum[D, F, I] =
HkdFieldInstances.OfSum(
summonAsArray[K11.LiftP[[C[_[_]]] =>> HkdFieldInstances[C, F, I], m.MirroredElemTypes]]
.asInstanceOf[Array[HkdFieldInstances[D, F, I]]]
)
}