-
Notifications
You must be signed in to change notification settings - Fork 19
Open
Description
Im not sure if issues is a correct place to request help, however I'm trying to understand Algae.Free
and it isn't as easy as it might be
There is link to an article on free monads in docs
I tried to implement Haskell code in Elixir, and here's what I've got:
import Algae
import TypeClass
use Witchcraft
defmodule Toy do
defsum do
defdata Output do
output :: any()
next :: any()
end
defdata Bell do
next :: any()
end
defdata(Done :: none())
end
defimpl TypeClass.Property.Generator, for: Toy.Output do
def generate(_) do
[1, 1.1, "", :a]
|> Enum.random()
|> Toy.Output.new()
end
end
defimpl TypeClass.Property.Generator, for: Toy.Bell do
def generate(_) do
[1, 1.1, "", :a]
|> Enum.random()
|> Toy.Bell.new()
end
end
defimpl TypeClass.Property.Generator, for: Toy.Done do
def generate(_), do: Toy.Done.new()
end
definst Witchcraft.Functor, for: Toy.Output do
def map(%{output: output, next: next}, fun), do: %Toy.Output{output: output, next: fun.(next)}
end
definst Witchcraft.Functor, for: Toy.Bell do
def map(%{next: next}, fun), do: %Toy.Bell{next: fun.(next)}
end
definst Witchcraft.Functor, for: Toy.Done do
def map(_, _), do: %Toy.Done{}
end
def of4(_, x) do
Algae.Free.new(x ~> (&Algae.Free.Pure.new/1))
end
def output(x), do: fn y -> Algae.Free.new(Toy.Output.new(x, Algae.Free.Pure.new(y))) end
def bell, do: fn y -> Algae.Free.new(Toy.Bell.new(Algae.Free.Pure.new(y))) end
def done, do: Algae.Free.new(Toy.Done.new())
def program do
monad Algae.Free.new() do
output(1)
bell()
end
end
end
And here is the confusing moment Toy.program.(nil)
returns %Algae.Free.Pure{pure: %Toy.Bell{next: %Algae.Free.Pure{pure: nil}}}
instead of %Toy.Output{next: %Algae.Free.Pure{pure: %Toy.Bell{next: %Algae.Free.Pure{pure: nil}}}, output: 1}
. It basically does not 'concatenate' previous value with the next one
Thanks in advance for your help!
Metadata
Metadata
Assignees
Labels
No labels