From 92b1ad56dec2a31bafdae94e3ffbc67855d545fe Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 13 Nov 2025 22:11:16 -0500 Subject: [PATCH 1/6] correctly constrain Cast types --- lib/drops/types/union.ex | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/drops/types/union.ex b/lib/drops/types/union.ex index 2c49eaf..31733f0 100644 --- a/lib/drops/types/union.ex +++ b/lib/drops/types/union.ex @@ -101,6 +101,12 @@ defmodule Drops.Types.Union do }) end + defp constrain(%Drops.Types.Cast{input_type: input_type} = type, predicates) do + Map.merge(type, %{ + input_type: constrain(input_type, predicates) + }) + end + defp constrain(type, predicates) do Map.merge(type, %{ constraints: type.constraints ++ infer_constraints(predicates) From 76316c12797dbf9a03d1b28d83defe1a519914d4 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 17 Nov 2025 23:12:35 -0500 Subject: [PATCH 2/6] handle constraints for "and" clauses --- lib/drops/types/union.ex | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/drops/types/union.ex b/lib/drops/types/union.ex index 31733f0..60c8415 100644 --- a/lib/drops/types/union.ex +++ b/lib/drops/types/union.ex @@ -108,8 +108,13 @@ defmodule Drops.Types.Union do end defp constrain(type, predicates) do + constraints = + case type.constraints do + {:and, constraints} -> {:and, constraints ++ infer_constraints(predicates)} + constraints when is_list(constraints) -> constraints ++ infer_constraints(predicates) + end Map.merge(type, %{ - constraints: type.constraints ++ infer_constraints(predicates) + constraints: constraints }) end end From 7b45631142ab56016820cb776a34a721011ba4b0 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 17 Nov 2025 23:15:50 -0500 Subject: [PATCH 3/6] make new/2 work like new/2 in other types --- lib/drops/type.ex | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/drops/type.ex b/lib/drops/type.ex index 840ee27..9885282 100644 --- a/lib/drops/type.ex +++ b/lib/drops/type.ex @@ -246,10 +246,11 @@ defmodule Drops.Type do ) end - def new(spec, constraints) when is_list(constraints) do - new( - primitive: infer_primitive(spec), - constraints: infer_constraints({:type, {spec, constraints}}) + def new(predicates, opts) when is_list(opts) do + type = new(opts) + Elixir.Map.merge( + type, + %{constraints: type.constraints ++ Drops.Type.infer_constraints(predicates)} ) end From 2ec119d5a1752d65c3df680ae9ec4091371e8cd4 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 20 Nov 2025 18:31:13 -0500 Subject: [PATCH 4/6] also handle :and clauses in new/2 in Drops.Type macro --- lib/drops/type.ex | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/drops/type.ex b/lib/drops/type.ex index 9885282..85c4030 100644 --- a/lib/drops/type.ex +++ b/lib/drops/type.ex @@ -248,9 +248,14 @@ defmodule Drops.Type do def new(predicates, opts) when is_list(opts) do type = new(opts) + constraints = + case type.constraints do + {:and, constraints} -> {:and, constraints ++ infer_constraints(predicates)} + constraints when is_list(constraints) -> constraints ++ infer_constraints(predicates) + end Elixir.Map.merge( type, - %{constraints: type.constraints ++ Drops.Type.infer_constraints(predicates)} + %{constraints: constraints} ) end From 4a5dbf4b4a30bcefcb2e9b8c1ea75c58ba552429 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Sat, 22 Nov 2025 09:30:08 -0500 Subject: [PATCH 5/6] correctly constrain Union types --- lib/drops/types/union.ex | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/drops/types/union.ex b/lib/drops/types/union.ex index 60c8415..98dbc52 100644 --- a/lib/drops/types/union.ex +++ b/lib/drops/types/union.ex @@ -107,6 +107,13 @@ defmodule Drops.Types.Union do }) end + defp constrain(%Drops.Types.Union{left: left, right: right} = type, predicates) do + Map.merge(type, %{ + left: constrain(left, predicates), + right: constrain(right, predicates) + }) + end + defp constrain(type, predicates) do constraints = case type.constraints do From b42f5c17a96fb5d073354ff9bc200be70f55b830 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Mon, 24 Nov 2025 23:43:28 -0500 Subject: [PATCH 6/6] fix list typespecs --- lib/drops/type/dsl.ex | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/drops/type/dsl.ex b/lib/drops/type/dsl.ex index 58f6a44..3e52a4f 100644 --- a/lib/drops/type/dsl.ex +++ b/lib/drops/type/dsl.ex @@ -73,9 +73,9 @@ defmodule Drops.Type.DSL do """ @doc since: "0.1.0" - @spec type({atom(), []}) :: type() + @spec type({atom(), list()}) :: type() @spec type(list: atom()) :: type() - @spec type(list: []) :: type() + @spec type(list: list()) :: type() @spec type([atom()]) :: [type()] @spec type(atom()) :: type() @@ -113,8 +113,8 @@ defmodule Drops.Type.DSL do """ @doc since: "0.1.0" - @spec type(atom(), []) :: type() - @spec type({:cast, {atom(), []}}, type()) :: type() + @spec type(atom(), list()) :: type() + @spec type({:cast, {atom(), list()}}, type()) :: type() def type([type | rest], predicates) do union([type | rest], predicates) @@ -251,7 +251,7 @@ defmodule Drops.Type.DSL do """ @doc since: "0.1.0" - @spec maybe(atom(), []) :: type() + @spec maybe(atom(), list()) :: type() def maybe(type, predicates \\ []) do type([nil, {type, predicates}]) @@ -289,7 +289,7 @@ defmodule Drops.Type.DSL do @doc since: "0.1.0" @spec string(atom()) :: type() - @spec string([]) :: type() + @spec string(list()) :: type() def string(predicate) when is_atom(predicate) do string([predicate]) @@ -335,7 +335,7 @@ defmodule Drops.Type.DSL do @doc since: "0.1.0" @spec integer(atom()) :: type() - @spec integer([]) :: type() + @spec integer(list()) :: type() def integer(predicate) when is_atom(predicate) do integer([predicate]) @@ -377,7 +377,7 @@ defmodule Drops.Type.DSL do """ @doc since: "0.1.0" - @spec float([]) :: type() + @spec float(list()) :: type() def float(predicates) when is_list(predicates) do type(:float, predicates) @@ -460,7 +460,7 @@ defmodule Drops.Type.DSL do @doc since: "0.1.0" @spec map(atom()) :: type() - @spec map([]) :: type() + @spec map(list()) :: type() def map(predicate) when is_atom(predicate) do map([predicate])