-
Notifications
You must be signed in to change notification settings - Fork 468
Explore ideas about flattened types. #5707
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
Comments
Introduce safe promises, based on #5707 - Add t-first Js.Promise2 with safe bindings - Remove type check for nested promises - Add example illustrating a typical example of nested promises, and how it goes away with Js.Promise2
Introduce safe promises, based on #5707 - Add t-first Js.Promise2 with safe bindings - Remove type check for nested promises - Add example illustrating a typical example of nested promises, and how it goes away with Js.Promise2
Introduce safe promises, based on #5707 - Add t-first Js.Promise2 with safe bindings - Remove type check for nested promises - Add example illustrating a typical example of nested promises, and how it goes away with Js.Promise2
What I didn't understand: Is this So that it would become possible to do both p->Js.Promise2.then(x => x + 1) and p->Js.Promise2.then(x => Js.Promise2.resolve(x + 1)) like in JS? |
It describes the meaning of the promise type in terms of its runtime representation: when you see What would be possible to expose, is that |
Introduce safe promises, based on #5707 - Add t-first Js.Promise2 with safe bindings - Remove type check for nested promises - Add example illustrating a typical example of nested promises, and how it goes away with Js.Promise2
Introduce safe promises, based on #5707 - Add t-first Js.Promise2 with safe bindings - Remove type check for nested promises - Add example illustrating a typical example of nested promises, and how it goes away with Js.Promise2
Introduce safe promises, based on #5707 - Add t-first Js.Promise2 with safe bindings - Remove type check for nested promises - Add example illustrating a typical example of nested promises, and how it goes away with Js.Promise2
Introduce safe promises, based on #5707 - Add t-first Js.Promise2 with safe bindings - Remove type check for nested promises - Add example illustrating a typical example of nested promises, and how it goes away with Js.Promise2
Introduce safe promises, based on #5707 - Add t-first Js.Promise2 with safe bindings - Remove type check for nested promises - Add example illustrating a typical example of nested promises, and how it goes away with Js.Promise2
Introduce safe promises, based on #5707 - Add t-first Js.Promise2 with safe bindings - Remove type check for nested promises - Add example illustrating a typical example of nested promises, and how it goes away with Js.Promise2
I think it's a dangerous way to go because it goes against the way how developers got used to thinking of the In my opinion, it breaks the reasoning about The actual problem is that And I think that it's better to leave the flattening to a user, by adding a helper Here's the preceding discussion: #5709 (comment). |
The flatten promise in Js reminds me of the linked list: // Flatten Promise
module FP = {
type rec t<'a> = Nil('a) | Cons(t<'a>)
let rec awaitP = (p: t<'a>) =>
switch p {
| Nil(a) => a
| Cons(p) => awaitP(p)
}
}
let ppp = FP.Cons(FP.Cons(FP.Cons(Nil(1))))
let p = FP.awaitP(ppp) 😉 |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Flattened Types
We study the properties of flattened type constructors
c<->
, i.e. types whose runtime representation has the semantic propertyc<c<'a>> = c<'a>
. Flattened types are common concepts in JavaScript: nullable values (or possibly undefined), and promises.Two semantic relations between types will be considered.
t1 <= t2
means that every JS value which is a runtime representation of typet1
is a value of typet2
; andt1 = t2
means that botht1 <= t2
andt2 <= t1
.Equations
We consider a unary type constructor
?<->
that obeys two equations:1
??t = ?t
2
t <= ?t
While equation 1 is self-evident, number 2 isn't. Consider that flattened types normally come with operations to "look inside", i.e. take a value of type
?t
, and later continue the computation with a value of typet
. If one starts with a value of type??t
and looks inside, then the computation expects to continue with a value of type?t
. However a value of type??t
, because of equation 1, also has type?t
, so the computation must be able to continue with typet
. And equation 2 is exactly what allows to provide a value of typet
to a computation expecting?t
.We will also use the injection
i : t => ?t
, the identity function, which exists because of equation 2.Option Instantiation
The Option Instantiation also has the two equations plus:
e
such thate:?t
for anyt
, the empty element.We define a function
caseAnalysis : (?t, s, t=>s) => s
in JS as follows:This is sufficient to interpret options:
None
ise
Some(x)
isi(x)
switch e { | None => e1 | Some(x) => e2 }
iscaseAnalysis(e, e1, x=>e2)
What is left to define is the type constructor
?t
for flattened options.The definition is
t | undefined
i.e. it takes all the values thatt
takes plus the valueundefined
.It's clear that equations 1 and 2 hold. Plus we can pick
e = undefined
.As for
caseAnalysis
ifo : ?t
ando == e
does not hold, than it must be thato : t
. So the function satisfies the required type.This gives an instance of flattened options that don't require special representation for the nested case. It differs from ordinary options in that
Some(None)
is the same value asNone
.Promise Instantiation
The Promise Instantiation has the two equations plus:
map : (?t, t=>s) => ?s
.With this we can interpret flattened promises:
FPromise.resolve
isi
FPromise.then_
ismap
Before defining the type
?
, we use an auxiliary definition for JS promises.The type
Promise<t>
of JS promises is defined as the set of values that are JS promises holding values of typet
. Each such valuev
has the propertyPromise.resolve(v) == v
.Now the type for flattened promises is defined as:
?t
ist | Promise<t>
so it's either a JS value of typet
or a JS promise holding a value of typet
.Let's see how this satisfies the required equations.
For equation 1,
??t
is?t | Promise<?t>
i.e.t | Promise<t> | Promise<t | Promise<t>>
i.e.t | Promise<t>
because JS promises are flattened, i.e.?t
.For equation 2, clearly
t <= t | Promise<t>
.What is left to do is to define
map
in JS, as follows:To check the type of
map
, assumep
has typet | Promise<t>
,then
Promise.resolve(p)
has typePromise<t>
so it's safe to applythen
and obtain the result of typePromise<s>
which also has type?s
.Compared to ordinary JS promise types,
?t
obeys property 2, which is what seems to protect it from issues when types are assigned to nested promises.Async/await requires no special interpretation. For example:
compiles to:
Now if
x
has type?t
, i.e. is a JS value of typet | Promise<t>
, then there are 2 cases:x
has typePromise<t>
thenawait x
has typet
t
and is not a promise, soawait x
isx
, which has typet
.The text was updated successfully, but these errors were encountered: