-
Notifications
You must be signed in to change notification settings - Fork 1
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
Const implementation without Fully Qualified Type Representatives #2
Comments
I think Constant.prototype['fantasy-land/ap'] = function(other){
return other.cata({
NoConst: () => this,
Const: otherContext => Constant.Const (
otherContext['fantasy-land/concat'] (getConst (otherContext.constructor) (this))
)
});
}; |
We can even make the Applicative implementation conditional, like done in other types to get better type introspection: //...
function Const(x){
const cnst = Object.create (Const$prototype);
if(Monoid.test(x)){
cnst['fantasy-land/ap'] = Const$prototype$ap;
}
}
//...
Applicative.test (Const ("_")) // true
Applicative.test (Const (42)) // false
Applicative.test (NoConst) // true |
Ah. I just remembered another idea David and I had: Since Lenses don't actually use the Applicative instance on Const, we could export two Const types from this library: One that just has Functor, and doesn't need a Monoid typeRep when evaluated. This one could be used for lens implementations. And the other being the Applicative Functor variant proposed above. |
Hello @Avaq. I think this is a pretty good idea. It's worth noting that any data AddPure f a = Pure a | Impure (f a)
instance Apply f => Applicative (AddPure f)
where
pure = Pure
Pure ab <*> Pure a = Pure $ ab a
Pure ab <*> Impure fa = Impure $ ab <$> fa
Impure fab <*> Pure a = Impure $ (\ab -> ab a) <$> fab
Impure fab <*> Impure fa = Impure $ fab <.> fa
interpret :: Apply f => (forall x. x -> f x) -> AddPure f a -> f a
interpret pure (Pure a) = pure a
interpret _ (Impure fa) = fa All this to say the approach you've outlined definitely works and gives a lawful Applicative. It's possible that a general purpose utility for "deferring" the pure implementation of |
Thanks for your thoughts @masaeedu!
My inclination would be to go with the const-specific approach initially, and extract out if we find ourselves duplicating the approach. |
During a recent conversation between @davidchambers and I, we came up with a way to define an Applicative Const Functor that can be used to implement Lenses, without needing a Monoid up front. The conversation is starting to escape my memory, so I'll just put the idea down here lest we forget.
The Problem
As I understand, the need for a Monoid on Const currently blocks progress on this library. In particular, there currently is no way to implement Fantasy Land's Applicative for Const in the way Haskell does:
Here we see
Applicative
implemented forConst m
by restricting tom
s that haveMonoid
, and just puttingmempty
as the actual context-value of theConst
. Haskell then relies on the type system to make it so whengetConst
is resolved, it gets a value of the correct specific Monoid.In JavaScript (and specifically, Fantasy Land as it is right now), we don't have a way to carry type information along with our Const instances so that when
getConst
is used, we can put a value of the correct Monoid there:Solutions
An alternative that I came up with is to have a binary type implementation for Const, where reliance on the type system is removed, and the fallback value is provided by the user when evaluating the Const:
A few observations:
NoConst ++ Const a = Const a
, etc)What do you think? Does this approach have any benefits over the one taken in #1 ?
/cc @masaeedu
The text was updated successfully, but these errors were encountered: