<F: FunctorX>
int he kind extension
where
though
addOne
can also be redefined as:
func addOne<F>(_ fa: Kind<F, Int>) -> Kind<F, Int> where F : FunctorX, F.F == F {
return fa.fmap({b in return b + 1})
}
if it doesn't scale maybe we need
protocol Typeclass {
associatedtype F = Self
protocol FunctorX: Typeclass {
extension EitherPartial : FunctorX {
static func fmap<A, B>(_ fa: Kind<Kind<F, A>, A>, _ f: (A) -> B) -> Kind<Kind<F, A>, B> {
// implementation
}
}
// type class
protocol FunctorX {
associatedtype F
static func fmap<A, B>(_ fa: Kind<F, A>, _ f : (A) -> B) -> Kind<F, B>
}
// syntax for all kinds adhering to the type class
extension Kind {
func fmap<B>(_ f: (A) -> B) -> Kind<F, B> where F : FunctorX, F.F == F {
return F.fmap(self, f)
}
}
// Maybe Functor instance
extension ForMaybe : FunctorX {
typealias F = ForMaybe
class func fmap<A, B>(_ fa: Kind<ForMaybe, A>, _ f: (A) -> B) -> Kind<ForMaybe, B> {
return fa.fix().map(f)
}
}
// example of polymorphic function using syntax over kinds
func addOne<F: FunctorX>(_ fa: Kind<F, Int>) -> Kind<F, Int> where F.F == F {
return fa.fmap({b in return b + 1})
}
extension EitherPartial : FunctorX {
static func fmap<B, C>(_ fa: Kind<Kind<ForEither, A>, B>, _ f: @escaping (B) -> C) -> Kind<Kind<ForEither, A>, C> {
return Either<A, B>.fix(fa)
.fold({ a in Either<A, C>.left(a) },
{ b in Either<A, C>.right(f(b)) })
}
}
this actually worksextension EitherPartial : FunctorX { static func fmap<B, C>(_ fa: Kind<Kind<ForEither, A>, B>, _ f: @escaping (B) -> C) -> Kind<Kind<ForEither, A>, C> { return Either<A, B>.fix(fa) .fold({ a in Either<A, C>.left(a) }, { b in Either<A, C>.right(f(b)) }) } }
class Three<A, B, C> : Kind3<ForThree, A, B, C>
and typealias ThreePartial<A, B> = Kind2<ForThree, A, B>
extension ThreePartial : FunctorX {
static func fmap<C, D>(_ fa: Kind<Kind<Kind<ForThree, A>, B>, C>, _ f: @escaping (C) -> D) -> Kind<Kind<Kind<ForThree, A>, B>, D> {
// Implementation
}
}
this says "Use of undeclared type B"
associatedtype
and they make the extension implement the functions but not the actual protocols themselves. Not sure how they can do ad hoc polymorphism then or if their type classes are just syntax over data types.