Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions lib/drops/type.ex
Original file line number Diff line number Diff line change
Expand Up @@ -246,10 +246,16 @@ 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)
constraints =
case type.constraints do
{:and, constraints} -> {:and, constraints ++ infer_constraints(predicates)}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made the minimal changes to make this work. But it looks like {:and, constraints} gets treated the same as just constraints, so I wonder if we can just get rid of {:and, ...} everywhere.

constraints when is_list(constraints) -> constraints ++ infer_constraints(predicates)
end
Elixir.Map.merge(
type,
%{constraints: constraints}
)
end

Expand Down
18 changes: 9 additions & 9 deletions lib/drops/type/dsl.ex
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,9 @@ defmodule Drops.Type.DSL do
"""
@doc since: "0.1.0"

@spec type({atom(), []}) :: type()
@spec type({atom(), list()}) :: type()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Elixir docs say that a typespec of [] means an empty list.

@spec type(list: atom()) :: type()
@spec type(list: []) :: type()
@spec type(list: list()) :: type()
@spec type([atom()]) :: [type()]
@spec type(atom()) :: type()

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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}])
Expand Down Expand Up @@ -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])
Expand Down Expand Up @@ -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])
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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])
Expand Down
20 changes: 19 additions & 1 deletion lib/drops/types/union.ex
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,27 @@ 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)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't sure if the constraint should be applied to the input type, the output type, or both.

})
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
{: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
Expand Down
Loading