Tam bir cevabın çok uzun bir hikaye olacağını söyleyerek başlayacağım ve geçen yazın büyük bir bölümünü in a blog post söyledim, bu yüzden burada bazı ayrıntıları gözden geçireceğim ve Cats için thing
'un bir çalışma uygulaması.
Bir başka tanıtım notu: bu makine artık Scalaz'da ve my pull request numaralı telefondan some of the "review"'da var. Kedilere sevindiğim için pek çok neden var. :) Hatta burada motive denemez tamamen opak tip sınıf için
İlk: Kediler anda birine sahip görünmüyor çünkü
case class SingletonOf[T, U <: { type A; type M[_] }](
widen: T { type A = U#A; type M[x] = U#M[x] }
)
object SingletonOf {
implicit def mkSingletonOf[T <: { type A; type M[_] }](implicit
t: T
): SingletonOf[T, t.type] = SingletonOf(t)
}
Sonra, bir IsoFunctor
tanımlayabilirsiniz :
import cats.arrow.NaturalTransformation
trait IsoFunctor[F[_], G[_]] {
def to: NaturalTransformation[F, G]
def from: NaturalTransformation[G, F]
}
object IsoFunctor {
implicit def isoNaturalRefl[F[_]]: IsoFunctor[F, F] = new IsoFunctor[F, F] {
def to: NaturalTransformation[F, F] = NaturalTransformation.id[F]
def from: NaturalTransformation[F, F] = to
}
}
Biz yaptığımız üzere olduğun şey için IsoFunctor
biraz daha basit birşey kullanabilirsiniz, ama buna ben Scalaz kullanılan ne güzel ilkeli tip sınıfı, ve, bu yüzden buraya o çakacağım . İki Unapply
örneklerini bunlara örnek olarak verilebilir bir yeni Unapply
için
Sonraki: herhangi kullanışlı örneklerini vardı önce tarihsel bir yan not olarak
import cats.Unapply
trait UnapplyProduct[TC[_[_]], MA, MB] {
type M[X]; type A; type B
def TC: TC[M]
type MA_ = MA
def _1(ma: MA): M[A]
def _2(mb: MB): M[B]
}
object UnapplyProduct {
implicit def unapplyProduct[
TC[_[_]], MA0, MB0,
U1 <: { type A; type M[_] },
U2 <: { type A; type M[_] }
](implicit
sU1: SingletonOf[Unapply[TC, MA0], U1],
sU2: SingletonOf[Unapply[TC, MB0], U2],
iso: IsoFunctor[U1#M, U2#M]
): UnapplyProduct[TC, MA0, MB0] {
type M[x] = U1#M[x]; type A = U1#A; type B = U2#A
} = new UnapplyProduct[TC, MA0, MB0] {
type M[x] = U1#M[x]; type A = U1#A; type B = U2#A
def TC = sU1.widen.TC
def _1(ma: MA0): M[A] = sU1.widen.subst(ma)
def _2(mb: MB0): M[B] = iso.from(sU2.widen.subst(mb))
}
}
, UnapplyProduct
Scalaz dört yıl süre yaşadı.
Ve şimdi yazabilir böyle bir şey: o zaman
import cats.Applicative
def thing[MA, MB](ma: MA, mb: MB)(implicit
un: UnapplyProduct[Applicative, MA, MB]
): Applicative[un.M] = un.TC
Ve:
scala> import cats.data.Xor
import cats.data.Xor
scala> thing(Xor.left[String, Int]("foo"), Xor.right[String, Char]('a'))
res0: cats.Applicative[[x]cats.data.Xor[String,x]] = [email protected]
Ve başarıyla böyle bir bu Xor
tip yıkmak için nasıl tanımlamak içine derleyici konuştum İlgili Applicative
örneğini görebildiğimiz yol (bu da geri dönüyoruz).
Dipnot olarak, 'SingletonOf' fikrinin% 100'ü Miles Sabin'e düşer (tabi ki): https://gist.github.com/milessabin/cadd73b7756fe4097ca0 –
Ugh, gerçekten Scala'dan gerçekten nefret ediyorum. Bizi böylesine büyük uzunluklara götürüyor. – wheaties