What is the Elixir typespec ok error?

svg viewer

Type spec

Elixir is a dynamically written language, so all the types are checked at runtime. Typespec notation is used in Elixir for two main purposes:

  • Declaring new data types using the pre-existing data types.
  • Declaring typed functions called specifications (spec).

Dynamic Dispatching

svg viewer

BehaviorsA way to separate generic parts of modules with specific parts are sometimes used along with dynamic dispatching. Dynamic Dispatching is used to behave as a middle-man between the behavior and all the functions adopting this behavior. It can be used to validate the output generated by the module before it is sent back to the user. Two atoms, :ok and :error, can be used with dynamic dispatching to make the program immune to errors.

Here is an example of a program that turns sentences upper-case or lower-case:

# Defining behaviour
defmodule CaseSensitive do
# Declaring callback to be used
@callback convert_case(sentence :: String) :: {:ok, String} | {:error, String}
# Dynamic Dispatching
def dispatcher!(implementation, contents) do
case implementation.convert_case(contents) do
{:ok, data} -> IO.puts(data)
{:error, error} -> raise ArgumentError, "#{error}"
end
end
end
# Function to make sentence uppercase
defmodule UpperCaseIt do
@behaviour CaseSensitive
@impl CaseSensitive
def convert_case(sentence) do
try do
{:ok, String.upcase(sentence)}
rescue
FunctionClauseError -> {:error, "Custom error message"}
end
end
end
# Function to make sentence lower case
defmodule LowerCaseIt do
@behaviour CaseSensitive
@impl CaseSensitive
def convert_case(sentence) do
try do
{:ok, String.downcase(sentence)}
rescue
FunctionClauseError -> {:error, "Custom error message"}
end
end
end
CaseSensitive.dispatcher!(UpperCaseIt, "turn this in uppercase")
CaseSensitive.dispatcher!(LowerCaseIt, "TURN THIS IN LOWER CASE")
CaseSensitive.dispatcher!(UpperCaseIt, 5555)

Explanation

  • (Line 2) A behavior module is declared named CaseSensitive.
  • (Line 4) All the modules adopting the CaseSensitive behavior will have to implement the @callback attributes in that behavior. In this case, there is only one attribute declared, convert_case.
  • (Line 4) convert_case takes string as input and returns a tuple: {:ok, String} returns if the execution is successful and {:error, String} if the execution fails.
  • (Line 7) A dynamic dispatcher is declared and named dispatcher!. This function acts as a mediator – it goes to a particular function and returns the value received from it.
  • (Line 16 & 31) The UpperCaseIt and LowerCaseIt functions are declared that contain the try/rescue block. The function tries to execute the task in the try block, .upcase() or .downcase(), and then return the tuple to dispatcher! accordingly.
  • (Line 45 & 46) The sentences are converted into upper-case and lower-case using the functions declared above.
  • (Line 47) Instead of a string, an integer is passed, which raises an error.

As a whole, this program has a couple of functions that execute their task and return the required result with an :ok atom upon success; upon failure, it returns an :error atom and a customized error message.

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved