[swift-evolution] [Proposal] Higher Kinded Types (Monads, Functors, etc.)

Will Fancher willfancher38 at gmail.com
Wed Dec 16 05:30:03 CST 2015


As a quick addendum, I'd like to point out that implementing Monad, Applicative, and Functor allows for some "free" code reuse. Functor can be defined expressly in terms of Applicative, which can be defined in terms of Monad.

    protocol Monad {
        typealias MonadType
        static func point(a: MonadType) -> Self
        func flatMap<MB where MB ~= Self>(f: MonadType -> MB) -> MB
    }

    protocol Applicative {
        typealias ApplicativeType
        static func pure(a: ApplicativeType) -> Self
        func apply<
                Func, Return
            where
                Func ~= Self, Return ~= Self,
                Func.ApplicativeType == (ApplicativeType -> Return.ApplicativeType)>
        (f: Func) -> Return
    }

    protocol Functor {
        typealias FunctorType
        func fmap<Return where Return ~= Self>(f: FunctorType -> Return.FunctorType) -> Return
    }

    extension Monad: Applicative {
        static func pure(a: MonadType) -> Self {
            return point(a)
        }

        func apply<
                Func, Return
            where
                Func ~= Self, Return ~= Self,
                Func.MonadType == (MonadType -> Return.MonadType)>
        (f: Func) -> Return {
            return f.flatMap { fn in
                return self.flatMap { m in
                    return point(fn(m))
                }
            }
        }
    }

    extension Applicative: Functor {
        func fmap<Return where Return ~= Self>(f: ApplicativeType -> Return.ApplicativeType) -> Return {
            return apply(pure(f))
        }
    }

The effect here is that just defining an implementation of Monad on a type gets Applicative and Functor for "free". Granted, those implementations are far from optimized, but they're free, and can be overridden for optimization. The point is, the higher kinded types in use here drastically reduce repetitive code by allowing common patterns like these definitions of Applicative and Functor to be abstracted.


More information about the swift-evolution mailing list