Type printer prints wider types on `non_empty_list` forms
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 56/100
Direzione di ricerca
Inizia da Module.Types.Descr e dal suo punto di ingresso del printer to_quoted_string/1, riproducendo gli esempi di non_empty_list dell’issue. Traccia il modo in cui vengono rappresentati i tipi terminatori e aggiungi una copertura di regressione per garantire che i tipi ricostruiti conservino il comportamento di equal?/subtype?, inclusa la disgiunzione delle liste proprie. Il lavoro è terminato quando le forme stampate non ampliano più i tipi originali.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Existing issue
- I have searched existing issues and could not find a duplicate.
Elixir and Erlang/OTP versions
Erlang/OTP 28 [erts-16.4.0.1] [source] [64-bit] [smp:12:12] [ds:12:12:10] [async-threads:1] [jit]
Interactive Elixir (1.21.0-dev)
Operating system
any
Current behavior
Module.Types.Descr printer emits non_empty_list/2 representation that when used directly produces a wider type.
The list representation stores the type of the terminator. The non_empty_list/2 constructor instead accepts a tail type and folds any list-valued part of that tail into the element type.
Repro:
When printed and reconstructed the reconstructed type admits proper lists when the original type only admits improper ones
import Module.Types.Descr
type =
non_empty_list(
none(),
opt_negation(list(term()))
)
to_quoted_string(type)
# => "non_empty_list(term(), not empty_list())"
reconstructed =
non_empty_list(
term(),
opt_negation(empty_list())
)
equal?(type, reconstructed)
# => false
subtype?(type, reconstructed)
# => true
subtype?(reconstructed, type)
# => false
proper_list = non_empty_list(integer())
disjoint?(type, proper_list)
# => true
subtype?(proper_list, reconstructed)
# => true
Another example:
reconstructed type admits [:not_an_integer] while original admits proper or improper lists of integers
original =
non_empty_list(
integer(),
opt_negation(non_empty_list(term(), term()))
)
to_quoted_string(original)
# => "non_empty_list(integer(), term())"
reconstructed = non_empty_list(integer(), term())
equal?(original, reconstructed)
# => false
subtype?(original, reconstructed)
# => true
subtype?(reconstructed, original)
# => false
Another example with gradual types:
original =
opt_difference(
non_empty_list(none(), term()),
list(dynamic())
)
to_quoted_string(original)
# => "dynamic(non_empty_list(term())) or non_empty_list(term(), not empty_list())"
reconstructed =
opt_union(
dynamic(non_empty_list(term())),
non_empty_list(term(), opt_negation(empty_list()))
)
to_quoted_string(reconstructed)
# => "non_empty_list(term(), term())"
equal?(original, reconstructed)
# => false
subtype?(original, reconstructed)
# => true
subtype?(reconstructed, original)
# => false
proper_list = non_empty_list(integer())
subtype?(proper_list, original)
# => false
subtype?(proper_list, reconstructed)
# => true
Expected behavior
Printed form should reconstruct the same type. Widening in the constructor is intentional and documented. Printer only documents "print the last type as term() if it only misses non empty lists." which suggests the current behavior is an unsafe optimization
- Lingua principale
- Elixir
- Stelle
- 26.7k
- Fork
- 3.7k
- Merge medio
- 8h 8m
- PR unite (30g)
- 61
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di elixir-lang/elixir
-
map_(get|put|update) ignore atom fields with static term() keyForse già presa @lukaszsamson l’ha presa 25 giorni fa. Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 45/100
elixir-lang/elixir#15932 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 55/100
elixir-lang/elixir#15909 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 64/100
elixir-lang/elixir#15900 ·
I maintainer di solito rispondono entro 1 giorno
-
Gradual map domain with `none` looses static part when computing lower boundForse già presa @lukaszsamson l’ha presa 43 giorni fa. Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
elixir-lang/elixir#15854 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 3/5 1-2 giorni Idoneità per principianti 52/100
elixir-lang/elixir#15829 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di elixir-lang/elixir
Issue simili
-
bug(bgp): every BGP routing upsert fails because ON CONFLICT names an index, not a constraintApertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 80/100
carverauto/serviceradar#5732 ·
I maintainer di solito rispondono entro 1 giorno
-
Markdown preview can show an outdated version of the cell sourceForse già presa @RaphaelFakhri l’ha presa 1 giorno fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
livebook-dev/livebook#3228 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 93/100
TomerAberbach/profiler-md#732 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 83/100
inertiajs/inertia-phoenix#84 ·
-
good first issue
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
beyond-all-reason/teiserver#1676 ·
I maintainer di solito rispondono entro 1 giorno