Typespec Drills
Mix.install([
{:jason, "~> 1.4"},
{:kino, "~> 0.9", override: true},
{:youtube, github: "brooklinjazz/youtube"},
{:hidden_cell, github: "brooklinjazz/hidden_cell"}
])
Navigation
Home Report An Issue Documentation And Static AnalysisGames: Documentation And Static AnalysisTypespec Drills
Drills help you develop familiarity and muscle memory with syntax through repeated exercises. Unlike usual problems, Drills are not intended to develop problem solving skills, they are purely for developing comfort and speed.
This set of drills is for typespecs. Follow the instructions for each drill and complete them as quickly as you can.
Review
You can define a function spec using the @spec
module attribute. Each @spec
includes the
function parameter types, and the return value type.
@spec add(integer(), integer()) :: integer()
def add(int1, int2) do
int1 + int2
end
You can define custom types using the @type
module attribute. These custom types can be used inside and outside of the current module.
@type user :: %{
name: string(),
age: integer()
}
You can include multiple types using the |
operator. This works for functions using @spec
and in custom types.
@spec double(integer() | nil)
Function Specs
Add function @spec
s based on the function parameter names and return value.
Example Solution
defmodule FunctionSpecs do
@spec do_nothing :: nil
def do_nothing do
nil
end
@spec accept_and_return_anything(any()) :: any()
def accept_and_return_anything(anything) do
anything
end
@spec double(float()) :: float()
def double(float) when is_float(float) do
float * 2.0
end
@spec double(integer()) :: integer()
def double(integer) when is_integer(integer) do
integer * 2
end
@spec double(number()) :: number()
def double(number) do
number * 2
end
@spec add(integer(), integer()) :: integer()
def add(integer1, integer2) do
integer1 + integer2
end
@spec multiply(integer(), integer()) :: integer()
def multiply(integer1, integer2) do
integer1 * integer2
end
@spec divide(integer(), integer()) :: float()
def divide(integer1, integer2) do
integer1 / integer2
end
@spec rounded_divide(integer(), integer()) :: integer()
def rounded_divide(integer1, integer2) do
div(integer1, integer2)
end
@spec concat(String.t(), String.t()) :: String.t()
def concat(string1, string2) do
string1 <> string2
end
@spec to_string(integer()) :: String.t()
def to_string(integer) do
Integer.to_string(integer)
end
@spec merge(map(), map()) :: map()
def merge(map1, map2) do
Map.merge(map1, map2)
end
@spec split_and_lowercase(String.t()) :: [String.t()]
def split_and_lowercase(string) do
string
|> String.downcase()
|> String.split("", trim: true)
end
@spec string_to_int(String.t()) :: integer()
def string_to_int(string) do
String.to_integer(string)
end
@spec integers_to_strings([integer()]) :: [String.t()]
def integers_to_strings(integers) do
Enum.map(integers, fn int -> Integer.to_string(int) end)
end
@spec one_to_two(1) :: 2
def one_to_two(1) do
2
end
end
defmodule FunctionSpecs do
def do_nothing do
nil
end
def accept_and_return_anything(anything) do
anything
end
def double(float) when is_float(float) do
float * 2.0
end
def double(integer) when is_integer(integer) do
integer * 2
end
def double(number) do
number * 2
end
def add(integer1, integer2) do
integer1 + integer2
end
def multiply(integer1, integer2) do
integer1 * integer2
end
def divide(integer1, integer2) do
integer1 / integer2
end
def rounded_divide(integer1, integer2) do
div(integer1, integer2)
end
def concat(string1, string2) do
string1 <> string2
end
def to_string(integer) do
Integer.to_string(integer)
end
def merge(map1, map2) do
Map.merge(map1, map2)
end
def split_and_lowercase(string) do
string
|> String.downcase()
|> String.split("", trim: true)
end
def string_to_int(string) do
String.to_integer(string)
end
def integers_to_strings(integers) do
Enum.map(integers, fn int -> Integer.to_string(int) end)
end
def one_to_two(1) do
2
end
end
Custom Types
Implement the following custom @type
s in the module below based on the comment describing them.
Example Solution
defmodule CustomTypes do
# a string or number
@type unparsed_number :: String.t() | number()
# a list of strings
@type strings :: [String.t()]
# a map with :title (string) and :content (string) keys.
@type book :: %{title: String.t(), content: String.t()}
# A map with :name (string) and `:books` (a list of books) keys.
@type author :: %{name: String.t(), books: [book()]}
end
defmodule CustomTypes do
# a string or number
@type unparsed_number
# a list of strings
@type strings
# a map with :title (string) and :content (string) keys.
@type book
# A map with :name (string) and `:books` (a list of books) keys.
@type author
end
Commit Your Progress
DockYard Academy now recommends you use the latest Release rather than forking or cloning our repository.
Run git status
to ensure there are no undesirable changes.
Then run the following in your command line from the curriculum
folder to commit your progress.
$ git add .
$ git commit -m "finish Typespec Drills exercise"
$ git push
We’re proud to offer our open-source curriculum free of charge for anyone to learn from at their own pace.
We also offer a paid course where you can learn from an instructor alongside a cohort of your peers. We will accept applications for the June-August 2023 cohort soon.