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

Add S combinator i.e. ap for (->) a #455

Open
infinity0 opened this issue Apr 25, 2020 · 4 comments
Open

Add S combinator i.e. ap for (->) a #455

infinity0 opened this issue Apr 25, 2020 · 4 comments

Comments

@infinity0
Copy link

The S combinator is occasionally useful for writing stuff in point-free style, if you're defining a type alias over a composition of the standard defunctionalisation symbols instead of writing your own type family.

In regular Haskell this is <*> for the (->) a instance of Applicative. However, for what I assume are hard technical reasons, neither (->) a nor (~>) a are instances of PApplicative / SApplicative in singletons, or any of the other expected classes for that matter. Nevertheless, the function doesn't require these instances and can be defined straightforwardly by itself:

singletons [d|
  ap :: (x -> y -> z) -> (x -> y) -> (x -> z)
  ap f g x = f x (g x)
  |]

which when promoted is essentially

type instance Apply (Ap f g) a = Apply (Apply f a) (Apply g a)

plus its defunctionalisation symbols. However I'm not sure the best name for it, ap is of course taken already by Monad.

@RyanGlScott
Copy link
Collaborator

However, for what I assume are hard technical reasons, neither (->) a nor (~>) a are instances of PApplicative / SApplicative in singletons, or any of the other expected classes for that matter.

Indeed. I've tried defining such instances myself, but I didn't get very far.

The purpose of this ap function seems sensible, but at the same time, it's not clear to me where in singletons would be a good home for it...

@infinity0
Copy link
Author

Data.Singletons.Prelude.Function would be a natural place, I think.

If overall name conflicts are OK, it could even be called ap - at least it doesn't conflict with anything in the singletons prelude, and you have to also import Monad.ap to get a conflict.

@RyanGlScott
Copy link
Collaborator

Data.Singletons.Prelude.Function would be a natural place, I think.

One issue with this is that that module is intended to just be a promoted/singled version of Data.Function from base. Your ap function doesn't correspond to anything from Data.Function, so it's a bit of an awkward fit.

@RyanGlScott
Copy link
Collaborator

I wonder if we should just wait until UnsaturatedTypeFamilies are implemented in GHC. Then we would be able to define this:

instance PApplicative ((~>) r) where
  type (f <*> g) = Ap f g

type family Ap (f :: r ~> a ~> b) (g :: r ~> a) (x :: r) :: b where
  Ap f g x = f x (g x)

And all would be well.

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

No branches or pull requests

2 participants