Skip to content

Commit

Permalink
Merge branch 'main' into witchcrafters#45-curried-constructor
Browse files Browse the repository at this point in the history
  • Loading branch information
expede authored Mar 14, 2021
2 parents 9cfab65 + 39922c6 commit 3ed3b10
Show file tree
Hide file tree
Showing 16 changed files with 261 additions and 230 deletions.
2 changes: 2 additions & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
erlang 22.0.5
elixir 1.9.4
186 changes: 182 additions & 4 deletions lib/algae/free.ex
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,16 @@ defmodule Algae.Free do
"""

alias Alage.Free.{Pure, Roll}
alias __MODULE__
alias Algae.Free.{Pure, Roll}

import Algae
use Witchcraft

use Witchcraft

defsum do
defdata Roll :: any() # Witchcraft.Functor.t()
defdata Pure :: any() \\ %Witchcraft.Unit{}
defdata(Roll :: any())
defdata(Pure :: any() \\ %Witchcraft.Unit{})
end

@doc """
Expand Down Expand Up @@ -111,3 +114,178 @@ defmodule Algae.Free do
|> wrap()
end
end

alias Algae.Free
alias Algae.Free.{Pure, Roll}
alias TypeClass.Property.Generator
alias Witchcraft.{Apply, Chain, Functor, Ord, Setoid}
import TypeClass
use Witchcraft

#############
# Generator #
#############

defimpl TypeClass.Property.Generator, for: Algae.Free.Pure do
def generate(_) do
[1, 1.1, "", []]
|> Enum.random()
|> Generator.generate()
|> Pure.new()
end
end

defimpl TypeClass.Property.Generator, for: Algae.Free.Roll do
def generate(_) do
inner = Algae.Id.new()

seed =
[1, 1.1, "", []]
|> Enum.random()
|> Generator.generate()

seed
|> Free.new()
|> Free.layer(inner)
|> Free.layer(inner)
end
end

##########
# Setoid #
##########

definst Witchcraft.Setoid, for: Algae.Free.Pure do
custom_generator(_) do
1
|> Generator.generate()
|> Pure.new()
end

def equivalent?(_, %Roll{}), do: false
def equivalent?(%Pure{pure: a}, %Pure{pure: b}), do: Setoid.equivalent?(a, b)
end

definst Witchcraft.Setoid, for: Algae.Free.Roll do
custom_generator(_) do
inner = Algae.Id.new()
seed = Generator.generate(1)

seed
|> Free.new()
|> Free.layer(inner)
|> Free.layer(inner)
end

def equivalent?(_, %Pure{}), do: false
def equivalent?(%Roll{roll: a}, %Roll{roll: b}), do: Setoid.equivalent?(a, b)
end

#######
# Ord #
#######

definst Witchcraft.Ord, for: Algae.Free.Pure do
custom_generator(_) do
1
|> TypeClass.Property.Generator.generate()
|> Free.new()
end

def compare(_, %Roll{}), do: :lesser
def compare(%Pure{pure: a}, %Pure{pure: b}), do: Ord.compare(a, b)
end

definst Witchcraft.Ord, for: Algae.Free.Roll do
custom_generator(_) do
inner = Algae.Id.new()
seed = Generator.generate(1)

seed
|> Free.new()
|> Free.layer(inner)
|> Free.layer(inner)
end

def compare(%Roll{}, %Pure{}), do: :greater
def compare(%Roll{roll: a}, %Roll{roll: b}), do: Ord.compare(a, b)
end

###########
# Functor #
###########

definst Witchcraft.Functor, for: Algae.Free.Pure do
def map(%Pure{pure: data}, fun), do: %Pure{pure: fun.(data)}
end

definst Witchcraft.Functor, for: Algae.Free.Roll do
def map(%Roll{roll: data}, fun) do
data
|> Functor.map(&Functor.map(&1, fun))
|> Roll.new()
end
end

#########
# Apply #
#########

definst Witchcraft.Apply, for: Algae.Free.Pure do
def convey(%Pure{pure: data}, %Pure{pure: fun}), do: %Pure{pure: fun.(data)}

def convey(pure, %Roll{roll: rolled}) do
rolled
|> Functor.map(&Apply.convey(pure, &1))
|> Roll.new()
end
end

definst Witchcraft.Apply, for: Algae.Free.Roll do
def convey(%Roll{roll: rolled}, %Pure{pure: fun}) do
rolled
|> Functor.map(&Functor.map(&1, fun))
|> Roll.new()
end

def convey(roll, %Roll{roll: rolled}) do
rolled
|> Functor.map(&Apply.convey(roll, &1))
|> Roll.new()
end
end

###############
# Applicative #
###############

definst Witchcraft.Applicative, for: Algae.Free.Pure do
def of(_, value), do: %Pure{pure: value}
end

definst Witchcraft.Applicative, for: Algae.Free.Roll do
def of(_, value), do: %Pure{pure: value}
end

#########
# Chain #
#########

definst Witchcraft.Chain, for: Algae.Free.Pure do
def chain(%Pure{pure: pure}, link), do: link.(pure)
end

definst Witchcraft.Chain, for: Algae.Free.Roll do
def chain(%Roll{roll: rolled}, link) do
rolled
|> Functor.map(&Chain.chain(&1, link))
|> Roll.new()
end
end

#########
# Monad #
#########

definst(Witchcraft.Monad, for: Algae.Free.Pure)
definst(Witchcraft.Monad, for: Algae.Free.Roll)
10 changes: 0 additions & 10 deletions lib/algae/free/applicative.ex

This file was deleted.

28 changes: 0 additions & 28 deletions lib/algae/free/apply.ex

This file was deleted.

16 changes: 0 additions & 16 deletions lib/algae/free/chain.ex

This file was deleted.

16 changes: 0 additions & 16 deletions lib/algae/free/functor.ex

This file was deleted.

29 changes: 0 additions & 29 deletions lib/algae/free/generator.ex

This file was deleted.

4 changes: 0 additions & 4 deletions lib/algae/free/monad.ex

This file was deleted.

32 changes: 0 additions & 32 deletions lib/algae/free/ord.ex

This file was deleted.

32 changes: 0 additions & 32 deletions lib/algae/free/setoid.ex

This file was deleted.

Loading

0 comments on commit 3ed3b10

Please sign in to comment.