Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Polymorphism big plans for Data and Control functor hierarchy #27

Open
aspiwack opened this issue Dec 20, 2018 · 1 comment
Open

Polymorphism big plans for Data and Control functor hierarchy #27

aspiwack opened this issue Dec 20, 2018 · 1 comment

Comments

@aspiwack
Copy link
Member

aspiwack commented Dec 20, 2018

Currently, data functors and control functors have type

fmap :: (a ->. b) -> f a ->. f b

and

fmap :: (a ->. b) ->. f a ->. f b

respectively. (that is data functors are regular functors and control functors are enriched functors).

But with polymorphism, it seem that we may want to split them further. Based more on how they are used (data functors are data containers of sorts, which control functors are effect-bearing computations).

My thoughts are the following: just like for lists the type of data functor's fmap would become

fmap :: (a # p -> b) -> f a # p -> f b

(it specialises to linear data functor when p ~ One and to regular (unrestricted) functor when p ~ Omega). It is not equivalent, but it seems to make sense. The only downside, though, is that it may be a bit weird for types which are always linear in the context (like a pure mutable array, for instance). An alternative is to do:

class Functor (p :: Multiplicity) f where
  fmap :: (a # p -> b) -> f a # p -> f b

This way we have polymorphism without the weirdness.

On the other hand, for control functors, we care about linearity of the control, but not linearity of the data. Therefore, we can the multiplicity of the data variable, like IO in the paper.

class Functor (f :: Multiplicity -> * -> *) where
  fmap :: (a ->. b) ->. f p a ->. f p b

(maybe a variant of type (a # p ->. b) ->. f q a ->. f (p * q)? Really the general form would be (a #p ->. Mult q b) ->. f p a ->. f q b).

The bottom-line is that control functors become functors from the category where objects are pairs (a, p) of an object and a type, and maps from (a, p) to (b, q) are a # p ->. Mult q b, to the category of types and linear functions (enriched in the category of types and linear functions).

This is not a restriction because you can always compose your old-style control functor with Mult p to obtain a new one. It also extends to a notion of monad (more precisely, of relative monad).

Which is the whole point of the change: it will make do notation much more pleasant, with the ability to return linear or unrestricted values.

@sjoerdvisscher
Copy link
Member

I think for data functors the domain and codomain should be allowed to differ? So:

fmap :: (a %p -> b) -> f a %q -> f b

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants