// 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.
Functor3
that I suggested above, but IMO it is wrong since they have both A
and B
associated with the protocol
Any
in order. So the Bifunctor
extensions which does not implement the protocol declare values for A, B etc which they don't have to fill in in other extensions https://github.com/typelift/Swiftz/blob/master/Sources/Swiftz/EitherExt.swift#L14
Maybe
for the option type, since the native version is named Optional
, but the guy posting the issue suggests to rename it to Option
to match Arrow and other libs conventions. I don't have a clear opinion on this and decided to go for Maybe
to make it easily distinguishable from the native one, but I'd like to hear other opinions as well.
Hi Good morning! I’m just playing around with bow and I have a noob question. I’m trying to writting a simple Yoneda but I ain’t able to do it :(
Here is my code:
let maybe = Either<String,Int>.right(2)
let h = Yoneda.functor(maybe)
And it’ saying Argument type 'Either<String, Int>' does not conform to expected type 'Functor'
Yoneda.functor(Either.functor())