All Projects → witchcrafters → Algae

witchcrafters / Algae

Licence: mit
Bootstrapped algebraic data types for Elixir

Programming Languages

elixir
2628 projects
dsl
153 projects

Projects that are alternatives of or similar to Algae

Datum
pure functional and generic programming for Erlang
Stars: ✭ 111 (-59.19%)
Mutual labels:  data-structures, algebraic-data-types
Imtools
Fast and memory-efficient immutable collections and helper data structures
Stars: ✭ 85 (-68.75%)
Mutual labels:  data-structures, algebraic-data-types
algos-and-data-structures
Interactive overview of common sorting algorithms, data structures, and miscellaneous algorithm challenges, implemented in JavaScript
Stars: ✭ 13 (-95.22%)
Mutual labels:  data-structures
Notes
算法刷题指南、Java多线程与高并发、Java集合源码、Spring boot、Spring Cloud等笔记,源码级学习笔记后续也会更新。
Stars: ✭ 256 (-5.88%)
Mutual labels:  data-structures
Mega Interview Guide
The MEGA interview guide, JavaSciript, Front End, Comp Sci
Stars: ✭ 255 (-6.25%)
Mutual labels:  data-structures
DSA
Implementation of various data structures and algorithms.
Stars: ✭ 15 (-94.49%)
Mutual labels:  data-structures
Floweaver
View flow data as Sankey diagrams
Stars: ✭ 266 (-2.21%)
Mutual labels:  data-structures
UMICollapse
Accelerating the deduplication and collapsing process for reads with Unique Molecular Identifiers (UMI). Heavily optimized for scalability and orders of magnitude faster than a previous tool.
Stars: ✭ 31 (-88.6%)
Mutual labels:  data-structures
Data Structures Algorithms
My implementation of 85+ popular data structures and algorithms and interview questions in Python 3 and C++
Stars: ✭ 273 (+0.37%)
Mutual labels:  data-structures
LeetCode-Py
⛽️「算法通关手册」,超详细的「算法与数据结构」基础讲解教程,「LeetCode」650+ 道题目 Python 版的详细解析。通过「算法理论学习」和「编程实战练习」相结合的方式,从零基础到彻底掌握算法知识。
Stars: ✭ 881 (+223.9%)
Mutual labels:  data-structures
Cpp
Repository for C++/C codes and algos.
Stars: ✭ 265 (-2.57%)
Mutual labels:  data-structures
awesome-free-courses
List of awesome free video courses for learning Computer Science!
Stars: ✭ 49 (-81.99%)
Mutual labels:  data-structures
js-collections-map-set
Repository to have example code to demonstrate JavaScript Map and Set data structures.
Stars: ✭ 21 (-92.28%)
Mutual labels:  data-structures
Javascript Datastructures Algorithms
📚 collection of JavaScript and TypeScript data structures and algorithms for education purposes. Source code bundle of JavaScript algorithms and data structures book
Stars: ✭ 3,221 (+1084.19%)
Mutual labels:  data-structures
algorithm
📌 Notes and Codes for studying data structures and algorithm
Stars: ✭ 72 (-73.53%)
Mutual labels:  data-structures
Embeddedsystem
📚 嵌入式系统基础知识与主流编程语言相关内容总结
Stars: ✭ 266 (-2.21%)
Mutual labels:  data-structures
finger-tree
🌵 Finger tree data structure for JavaScript
Stars: ✭ 20 (-92.65%)
Mutual labels:  data-structures
DataStructure.Samples.CSharp
数据结构示例程序(C#语言描述)
Stars: ✭ 103 (-62.13%)
Mutual labels:  data-structures
Jschema
A simple, easy to use data modeling framework for JavaScript
Stars: ✭ 261 (-4.04%)
Mutual labels:  data-structures
Arcus
ARCUS is the NAVER memcached with lists, sets, maps and b+trees. http://naver.github.io/arcus
Stars: ✭ 273 (+0.37%)
Mutual labels:  data-structures

Build Status Inline docs Deps Status hex.pm version API Docs license

Algae provides a boilerplate-avoiding DSL for defining algebraic data types (ADTs), plus several common structures

Quickstart

Add Algae to your list of dependencies in mix.exs:

def deps do
  [{:algae, "~> 1.2"}]
end

Table of Contents


NOTE
Please import Algae before trying out the examples below. The samples assume that is has already been done to remove the unnecessary clutter.


Product Builder

Build a product type

Includes:

  • Struct
  • Type definition
  • Constructor function (for piping and defaults)
  • Implicit defaults for simple values

Definition DSL

For convenience, several variants of the DSL are available.

Standard

defmodule Player do
  # =============== #
  # Data Definition #
  # =============== #

  defdata do
    name       :: String.t()
    hit_points :: non_neg_integer()
    experience :: non_neg_integer()
  end

  # =================== #
  #    Rest of Module   #
  # (business as usual) #
  # =================== #

  @spec attack(t(), t()) :: {t(), t()}
  def attack(%{experience: xp} = player, %{hit_points: hp} = target) do
    {
      %{player | experience: xp + 50},
      %{target | hit_points: hp - 10}
    }
  end
end

#=> %Player{name: "Sir Bob", hit_points: 10, experience: 500}

Single Field Shorthand

Without any fields specified, Algae will default to a single field with the same name as the module (essentially a "wrapper type"). You must still provide the type for this field, however.

Embedded in another module:

defmodule Id do
  defdata any()
end

%Id{}
#=> %Id{id: nil}

Standalone:

defdata Wrapper :: any()

%Wrapper{}
#=> %Wrapper{wrapper: nil}

Constructor

A helper function, especially useful for piping. The order of arguments is the same as the order that they are defined in.

defmodule Person do
  defdata do
    name :: String.t()
    age  :: non_neg_integer()
  end
end

Person.new("Rachel Weintraub")
#=> %Person{
#     name: "Rachel Weintraub",
#     age:  0
#   }

Constructor Defaults

Fields will automatically default to a sensible value (a typical "zero" for that datatype). For example, non_neg_integer() will default to 0, and String.t() will default to "".

You may also overwrite these defaults with the \\ syntax.

defmodule Pet do
  defdata do
    name      :: String.t()
    leg_count :: non_neg_integer() \\ 4
  end
end

Pet.new("Crookshanks")
#=> %Pet{
#     name: "Crookshanks",
#     leg_count: 4
#   }

Pet.new("Paul the Psychic Octopus", 8)
#=> %Pet{
#     name: "Paul the Psychic Octopus",
#     leg_count: 8
#   }

This overwriting syntax is required for complex types:

defdata Grocery do
  item :: {String.t(), integer(), boolean()} \\ {"Orange", 4, false}
end

Grocery.new()
#=> %Grocery{
#     item: {"Orange", 4, false}
#   }

Overwrite Constructor

The new constructor function may be overwritten.

defmodule Constant do
  defdata :: fun()

  def new(value), do: %Constant{constant: fn _ -> value end}
end

fourty_two = Constant.new(42)
fourty_two.constant.(33)
#=> 42

Empty Tag

An empty type (with no fields) is definable using the none() type

defmodule Nothing do
  defdata none()
end

Nothing.new()
#=> %Nothing{}

Sum Builder

Build a sum (coproduct) type from product types

defmodule Light do
  # ============== #
  # Sum Definition #
  # ============== #

  defsum do
    defdata Red    :: none()
    defdata Yellow :: none()
    defdata Green  :: none()
  end

  # =================== #
  #    Rest of Module   #
  # (business as usual) #
  # =================== #

  def from_number(1), do: %Light.Red{}
  def from_number(2), do: %Light.Yellow{}
  def from_number(3), do: %Light.Green{}
end

Light.new()
#=> %Light.Red{}

Embedded Products

Data with multiple fields can be defined directly as part of a sum

defmodule Pet do
  defsum do
    defdata Cat do
      name :: String.t()
      claw_sharpness :: String.t()
    end

    defdata Dog do
      name :: String.t()
      bark_loudness :: non_neg_integer()
    end
  end
end

Default Constructor

The first defdata's constructor will be the default constructor for the sum

defmodule Maybe do
  defsum do
    defdata Nothing :: none()
    defdata Just    :: any()
  end
end

Maybe.new()
#=> %Maybe.Nothing{}

Tagged Unions

Sums join existing types with tags: new types to help distinguish the context that they are in (the sum type)

defdata Book  :: String.t() \\ "War and Peace"
defdata Video :: String.t() \\ "2001: A Space Odyssey"

defmodule Media do
  defsum do
    defdata Paper :: Book.t()
    defdata Film  :: Video.t() \\ Video.new("A Clockwork Orange")
  end
end

media = Media.new()
#=> %Paper{
#      paper: %Book{
#        book: "War and Peace"
#      }
#   }

A Sampling of ADTs

See complete docs for more

Algae.Id

The simplest ADT: a simple wrapper for some data

%Algae.Id{id: "hi!"}

Algae.Maybe

Maybe represents the presence or absence of something.

Please note that nil is actually a value, as it can be passed to functions! nil is not bottom!

Algae.Maybe.new()
#=> %Algae.Maybe.Nothing{}

Algae.Maybe.new(42)
#=> %Algae.Maybe.Just{just: 42}

Tree.BinarySearch

alias Algae.Tree.BinarySearch, as: BTree

#   42
#  /  \
# 77  1234
#     /  \
#    98  32

BTree.Branch.new(
  42,
  BTree.Branch.new(77),
  BTree.Branch.new(
    1234,
    BTree.Branch.new(98),
    BTree.Branch.new(32)
  )
)

#=> %Algae.Tree.BinarySearch.Branch{
#     value: 42,
#     left: %Algae.Tree.BinarySearch.Branch{
#       value: 77,
#       left:  %Algae.Tree.BinarySearch.Empty{},
#       right: %Algae.Tree.BinarySearch.Empty{}
#     },
#     right: %Algae.Tree.BinarySearch.Branch{
#       value: 1234,
#       left:  %Algae.Tree.BinarySearch.Branch{
#         value: 98,
#         left:  %Algae.Tree.BinarySearch.Empty{},
#         right: %Algae.Tree.BinarySearch.Empty{}
#       },
#       right: %Algae.Tree.BinarySearch.Branch{
#         value: 32,
#         left:  %Algae.Tree.BinarySearch.Empty{},
#         right: %Algae.Tree.BinarySearch.Empty{}
#       }
#     }
#   }
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].