Created
December 27, 2021 16:26
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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