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

Profunctor combinators #77

Open
guaraqe opened this issue Feb 10, 2020 · 8 comments
Open

Profunctor combinators #77

guaraqe opened this issue Feb 10, 2020 · 8 comments
Assignees

Comments

@guaraqe
Copy link

guaraqe commented Feb 10, 2020

These are lens-like combinators that could be used for manipulating arrows in funflow and porcupine. They are based on the code in the profunctor-optics library.

The definition of an Optic in this library is:

type Optic p s t a b = p a b -> p s t

Since these optics are functions, they can be composed with the (.) operator.

Lens

The definition of a Lens in the library is:

type Lens s t a b = forall p. Strong p => Optic p s t a b 

which means that the two functions that compose the Strong class can be considered as lenses:

first' :: forall p. Strong p => p a b -> p (a, c) (b, c)
first' :: Lens (a,c) (b,c) a b

second' :: forall p. Strong p => p a b -> p (c, a) (c, b) 
second' :: Lens (c,a) (c,b) a b

Other lenses can be constructed using the general lens function.

Prism

The definition of a Prism in the library is:

type Prism s t a b = forall p. Prism p => Optic p s t a b 

which means that the two functions that compose the Choice class can be considered as prisms:

left' :: forall p. Choice p => p a b -> p (Either a c) (Either b c)
left' :: Prism (Either a c) (Either b c) a b

right' :: forall p. Choice p => p a b -> p (Either c a) (Either c b) 
right' :: Prism (Either c a) (Either c b) a b

Other prisms can be constructed using the general prism function.

Traversal

The definition of a Traversal in the library is different from what I would expect. For a good reason I imagine. But if we keep in the same track as in the other optics, we can take inspiration from the Traversing class, and define for ourselves the following:

type Traversable s t a b = forall p. Traversing p => Optic p s t a b 

which would mean that the base function from the Traversing class defines a traversal:

traverse' :: Traversable f => p a b -> p (f a) (f b) 
traverse' :: Traversal (f a) (f b) a b

Other traversals can be constructed using the wander function, that belongs to the same class:

wander :: (forall f. Applicative f => (a -> f b) -> s -> f t) -> Traversal s t a b 
@YPares
Copy link
Owner

YPares commented Feb 10, 2020

Thanks @guaraqe I opened an issue in cmk/profunctor-optics#26 to ask about that Traversal situation.

@YPares
Copy link
Owner

YPares commented Feb 10, 2020

Hmm. I just noticed that Cayley in profunctors (the one we use in porcupine) doesn't instanciate Traversing. Maybe that requirement over Traversing might be too constraining too. Or maybe the instance for Cayley could be written but just hasn't.

@guaraqe
Copy link
Author

guaraqe commented Feb 11, 2020

I think it was just not written:

liftTraverse ::
  Functor f =>
  (p a b -> p (t a) (t b)) ->
  Cayley f p a b -> Cayley f p (t a) (t b)
liftTraverse f (Cayley p) = Cayley (fmap f p)

@YPares
Copy link
Owner

YPares commented Feb 11, 2020

@guaraqe Nice :) Do you want to open a PR to profunctors with that?

@guaraqe
Copy link
Author

guaraqe commented Feb 11, 2020

Done: ekmett/profunctors#82

@guaraqe
Copy link
Author

guaraqe commented Feb 11, 2020

In another profunctor optics library, the definition I proposed above is the one used for Traversal: https://github.com/ChrisPenner/proton/blob/master/src/Proton/Traversal.hs

The library is from the author of "Optics by example", so there are good chances this is good.

@YPares YPares self-assigned this Feb 20, 2020
@YPares
Copy link
Owner

YPares commented Feb 20, 2020

This should be merged soon.

@guaraqe
Copy link
Author

guaraqe commented Feb 21, 2020

Are you just waiting for the merge of folds?

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