6

A FunList is a datatype invented by Twan van Laarhoven in this blog post. A minor variation given by Bartosz Milewski looks like this:

data FunList a b t = Done t 
                   | More a (FunList a b (b -> t))

An interesting fact about this datatype is that if we shuffle around the type parameters a bit, we have a Profunctor:

data FunList t b a
  = Done t 
  | More a (FunList (b -> t) b a)

mapResult :: (a -> b) -> FunList a x y -> FunList b x y
mapResult f (Done x)   = Done $ f x
mapResult f (More a r) = More a $ mapResult (f .) r

instance Profunctor (FunList t)
  where
  dimap _ _ (Done t) = Done t
  dimap f g (More a r) = More (g a) $ dimap f g $ mapResult (. f) r

Obeying dimap id id = id and dimap (f . g) (h . i) = dimap g h . dimap f i

The class Profunctor has several useful subclasses that represent families of profunctors (in the category theory sense) with additional equipment. Specifically, we can talk about profunctors with a "strength":

class Profunctor p => Strong t1 t2 p
  where
  pstrength :: p a b -> p (t1 a x) (t2 b x)

With laws dictated by the categorical notion of a "strong monad in a bicategory" (this is explained in detail in "Arrows are Strong Monads" by Kazuyuki Asada).

Similarly, since profunctors are "just" functors, we can look for whether a profunctor is monoidal:

class Profunctor p => SemigroupalProfunctor t1 t2 t3 p
  where
  combine :: t3 (p a b) (p c d) -> p (t1 a c) (t2 b d)

class SemigroupalProfunctor t1 t2 t3 p => MonoidalProfunctor t1 i1 t2 i2 t3 i3 p
  where
  unit :: i3 -> p i1 i2

With laws given by the definition of a monoidal functor.

Some interesting choices for t1, t2, t3 and i1, i2, i3 are (,), Either, These and () and Void respectively.

The question is which such classes does the reshuffled FunList instantiate? An implementation with some argument as to why it follows the laws would be very good, a proof of correctness would be excellent.

TODO: Specialize out list of laws for each class here

Asad Saeeduddin
  • 46,193
  • 6
  • 90
  • 139
  • 2
    This seems like a question you could go a long ways toward answering yourself by attempting to implement `pstrength`, `combine`, and `unit` yourself. Any problems you have implementing *one* of them would make for a good question. – chepner Nov 20 '20 at 20:41
  • @chepner This is true, but as a single person I have a limited amount of time and expertise (e.g. right now I have next to no time, and don't want to just discard this question). I think the promise of Stack Overflow is that we can provide a forum for collecting answers to an interesting question that draws on the expertise of many people. – Asad Saeeduddin Nov 20 '20 at 20:52
  • 1
    Please read https://stackoverflow.com/help/on-topic. – chepner Nov 20 '20 at 20:56
  • I think you’ll get a better discussion if you post this on https://www.reddit.com/r/haskell – Sjoerd Visscher Nov 21 '20 at 08:56

0 Answers0