Skip to content

Instantly share code, notes, and snippets.

@semmons99
Last active August 29, 2015 14:21
Show Gist options
  • Save semmons99/e2a39a8a085d01df1f16 to your computer and use it in GitHub Desktop.
Save semmons99/e2a39a8a085d01df1f16 to your computer and use it in GitHub Desktop.
defmodule Num do
defstruct [:val]
defimpl String.Chars do
def to_string(element), do: "#{element.val}"
end
end
defmodule Add do
defstruct [:left, :right]
defimpl String.Chars do
def to_string(element), do: "#{element.left} + #{element.right}"
end
end
defmodule Mul do
defstruct [:left, :right]
defimpl String.Chars do
def to_string(element), do: "#{element.left} * #{element.right}"
end
end
defmodule VM do
def eval(formula) do
IO.puts "humanized: #{formula}"
IO.puts reduce(formula)
end
def reduce(%Num{val: val}), do: %Num{val: val}
def reduce(%Add{left: left, right: right}), do: %Num{val: reduce(left).val + reduce(right).val}
def reduce(%Mul{left: left, right: right}), do: %Num{val: reduce(left).val * reduce(right).val}
end
defmodule App do
def run do
num = &(%Num{val: &1})
add = &(%Add{left: &1, right: &2})
mul = &(%Mul{left: &1, right: &2})
formula = add.(
mul.(num.(1), num.(2)),
mul.(num.(3), num.(4))
)
VM.eval(formula)
end
end
App.run
defprotocol Reduce do
def reduce(element)
end
defmodule Num do
defstruct [:val]
defimpl String.Chars do
def to_string(element), do: "#{element.val}"
end
defimpl Reduce do
def reduce(element), do: element
end
end
defmodule Add do
defstruct [:left, :right]
defimpl String.Chars do
def to_string(element), do: "#{element.left} + #{element.right}"
end
defimpl Reduce do
def reduce(element), do: %Num{val: reduce(element.left).val + reduce(element.right).val}
end
end
defmodule Mul do
defstruct [:left, :right]
defimpl String.Chars do
def to_string(element), do: "#{element.left} * #{element.right}"
end
defimpl Reduce do
def reduce(element), do: %Num{val: reduce(element.left).val * reduce(element.right).val}
end
end
defmodule VM do
import Reduce
def eval(formula) do
IO.puts "humanized: #{formula}"
IO.puts reduce(formula)
end
end
defmodule App do
def run do
num = &(%Num{val: &1})
add = &(%Add{left: &1, right: &2})
mul = &(%Mul{left: &1, right: &2})
formula = add.(
mul.(num.(1), num.(2)),
mul.(num.(3), num.(4))
)
VM.eval(formula)
end
end
App.run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment