Skip to content

Commit

Permalink
Derive
Browse files Browse the repository at this point in the history
  • Loading branch information
lpil committed Nov 21, 2019
1 parent 4770d54 commit b93b0bf
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 13 deletions.
67 changes: 67 additions & 0 deletions derive.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// # EnumerateEnum
//
// Derive a function that lists all varients of an enum.
// Only works for enums where all of the variant constructors have the same
// type i.e. they all have the same number of arguments of the same type. Most
// likely none.
//
// list()
// => [North, East, South, West]
//

pub enum Cardinal {
North
East
South
West
}

pub fn list() -> List(Cardinal)
= derive EnumerateEnum

// # Coerse
//
// Safely Coerse one type into another that has the same runtime
// representation.
//
// into_result(Error(1))
// => Error(1)
//
// OK, this one is hard to display here... Basically it's just a no-op.

pub enum MyError {
Error(a)
}

pub fn into_result(Error(err)) -> Result(b, err)
= derive Coerse

// # Compare
//
// Compare two values from an enum where the variant constructors take no
// arguments. The ordering is based upon the ordering the variants are
// described- smallest comes first.
//
// compare(Small, Medium)
// => order.Lt
//
// compare(Medium, Medium)
// => order.Eq
//
// compare(Large, Medium)
// => order.Gt
//

pub enum TshirtSize {
Small
Medium
Large
}

// TODO: Update the external fn syntax to match this new derive one

pub fn compare(TshirtSize, TshirtSize) -> order.Order
= derive Compare

pub fn compare(TshirtSize, TshirtSize) -> order.Order
= external "my_mod" "compare"
23 changes: 10 additions & 13 deletions traits.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub trait Named {

// compiled to
// -record(namedTrait, {name=undefined}).
// namedTrait_name(Trait) -> element(1, Trait).
// namedTrait_name(Trait) -> element(2, Trait).

// Use the trait, taking any arguments that implement the trait

Expand All @@ -20,13 +20,13 @@ fn whats_the_name(n: Named) -> String {
// whats_the_name(N, N_Named) ->
// gleam@string:append(<<"the name is: ">>, (namedTrait_name(N_Named))(N)).

fn two_names(x: Named, y: Named) -> struct(String, String) {
struct(name(x), name(y))
fn have_same_name(x: Named, y: Named) -> Bool {
name(x) == name(y)
}

// compiles to
// two_names(X, X_Named, Y, Y_Named) ->
// {(namedTrait_name(X_Named))(X), (namedTrait_name(Y_Named))(Y)}.
// have_same_name(X, X_Named, Y, Y_Named) ->
// (namedTrait_name(X_Named))(X) =:= (namedTrait_name(Y_Named))(Y).

// Define some types that implement the trait

Expand All @@ -43,7 +43,8 @@ let trait Cat: Named {

// compiles to
// namedTrait_Cat() ->
// {fun namedTrait_Cat_name/1}.
// {namedTrait,
// fun namedTrait_Cat_name/1}.
// namedTrait_Cat_name(Self) ->
// {cat, Name} = Self,
// Name.
Expand Down Expand Up @@ -89,14 +90,16 @@ let trait Wrapper(x: Named): Named {

// compiles to
// namedTrait_Wrapper_name(X) ->
// {namedTrait_trait_Wrapper_name(X)}.
// {namedTrait,
// namedTrait_trait_Wrapper_name(X)}.
// namedTrait_Wrapper_name(X_Name) ->
// fun(Self) ->
// {wrapper, Name} = X,
// (namedTrait_name(X_Name))(Name).
// end.

// Deriving trait implementations
// The compiler can have built in support for a bunch of traits

pub enum Size {
Small
Expand All @@ -109,9 +112,3 @@ derive trait Size: Eq
derive trait Size: Order
derive trait Size: FromAny
derive trait Size: ToAny

pub struct Box(b) {
boxed: b
}

derive trait Box(Eq): Eq

0 comments on commit b93b0bf

Please sign in to comment.