Skip to content

Instantly share code, notes, and snippets.

@mrroot5
Created December 27, 2021 16:26
Show Gist options
  • Save mrroot5/5da60f340a116c77dbb621538153b5d5 to your computer and use it in GitHub Desktop.
Save mrroot5/5da60f340a116c77dbb621538153b5d5 to your computer and use it in GitHub Desktop.
Elixir type protocol like Python. Keywrods: elixir, protocols, elixir protocols, type, elixir type, polymorphism, elixir polymorphism
defprotocol TypeProtocol do
@doc """
TypeProtocol checks a term type.
"""
@spec type(t) :: String.t()
def type(value)
end
defimpl TypeProtocol, for: Float do
@spec type(float) :: String.t()
def type(_value), do: "float"
end
defimpl TypeProtocol, for: Integer do
@spec type(integer) :: String.t()
def type(_value), do: "integer"
end
defimpl TypeProtocol, for: Atom do
@spec type(atom) :: String.t()
def type(value) do
cond do
is_boolean(value) -> "boolean"
is_nil(value) -> "nil"
true -> "atom"
end
end
end
defimpl TypeProtocol, for: BitString do
@spec type(binary) :: String.t()
def type(value) do
if is_binary(value) do
"binary"
else
"bitstring"
end
end
end
defimpl TypeProtocol, for: Function do
@spec type(function) :: String.t()
def type(_value), do: "function"
end
defimpl TypeProtocol, for: List do
@spec type(list) :: String.t()
def type(_value), do: "list"
end
defimpl TypeProtocol, for: Tuple do
@spec type(tuple) :: String.t()
def type(_value), do: "tuple"
end
defimpl TypeProtocol, for: Map do
@spec type(map) :: String.t()
def type(_value), do: "map"
end
defimpl TypeProtocol, for: MapSet do
@spec type(MapSet.t()) :: String.t()
def type(_value), do: "mapset"
end
defimpl TypeProtocol, for: PID do
@spec type(pid) :: String.t()
def type(_value), do: "pid"
end
defimpl TypeProtocol, for: Any do
@spec type(any) :: nil
def type(_value), do: nil
end
defmodule TypeProtocolTest do
@moduledoc """
TypeProtocolTest is a module for testing the TypeProtocol functions.
"""
use ExUnit.Case, async: true
doctest TypeProtocol
@derive TypeProtocol
test "return string" do
assert TypeProtocol.type(<<3::4>>) == "bitstring"
end
test "return possitve integer" do
assert TypeProtocol.type(10) == "integer"
end
test "return negative integer" do
assert TypeProtocol.type(-10) == "integer"
end
test "return possitve float" do
assert TypeProtocol.type(10.5) == "float"
end
test "return negative float" do
assert TypeProtocol.type(-10.5) == "float"
end
test "return atom" do
assert TypeProtocol.type(:myatom) == "atom"
end
test "return true boolean" do
assert TypeProtocol.type(true) == "boolean"
end
test "return false boolean" do
assert TypeProtocol.type(false) == "boolean"
end
test "return binary" do
assert TypeProtocol.type(<<0, 255, 42>>) == "binary"
end
test "return function" do
assert TypeProtocol.type(&Math.zero?/1) == "function"
end
test "return list" do
assert TypeProtocol.type([]) == "list"
end
test "return tuple" do
assert TypeProtocol.type({}) == "tuple"
end
test "return map" do
assert TypeProtocol.type(%{}) == "map"
end
test "return mapset" do
assert TypeProtocol.type(MapSet.new()) == "mapset"
end
test "return pid" do
assert TypeProtocol.type(self) == "pid"
end
test "return nil" do
assert TypeProtocol.type(nil) == "nil"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment