Search code examples
haskellfunctional-programmingfunctorquickcheckcategory-theory

What is the general case of QuickCheck's promote function?


What is the general term for a functor with a structure resembling QuickCheck's promote function, i.e., a function of the form:

promote :: (a -> f b) -> f (a -> b)

(this is the inverse of flip $ fmap (flip ($)) :: f (a -> b) -> (a -> f b)). Are there even any functors with such an operation, other than (->) r and Id? (I'm sure there must be). Googling 'quickcheck promote' only turned up the QuickCheck documentation, which doesn't give promote in any more general context AFAICS; searching SO for 'quickcheck promote' produces no results.


Solution

  • So far I found these ways of constructing an f with the promote morphism:

    • f = Identity
    • if f and g both have promote then the pair functor h t = (f t, g t) also does
    • if f and g both have promote then the composition h t = f (g t) also does
    • if f has the promote property and g is any contrafunctor then the functor h t = g t -> f t has the promote property

    The last property can be generalized to profunctors g, but then f will be merely a profunctor, so it's probably not very useful, unless you only require profunctors.

    Now, using these four constructions, we can find many examples of functors f for which promote exists:

    f t = (t,t)
    
    f t = (t, b -> t)
    
    f t = (t -> a) -> t
    
    f t = ((t,t) -> b) -> (t,t,t)
    
    f t = ((t, t, c -> t, (t -> b) -> t) -> a) -> t
    

    Also note that the promote property implies that f is pointed.

    point :: t -> f t
    point x = fmap (const x) (promote id)
    

    Essentially the same question: Is this property of a functor stronger than a monad?