Giter Club home page Giter Club logo

monax's Introduction

Monax macro library.

This library, built on top of Haxe macros give the user the possibility to define specific Monad instance and get automatically access to a haskell like sugared syntax.
About monad: http://en.wikipedia.org/wiki/Monad_(functional_programming)#Background

The syntactic sugar rely on the existence ‘ret’ and ‘flatMap’ in the Monad instance.
It also requiers the existence of ‘map’ to provide automatic optimisations.

Learn the (not so) hard way – Defining a Monad instance.



package mypackage;

class OptionM {

  public static function monad<T>(o : Option<T>) return OptionM; // will help with syntactic Sugar (see below)
    
  @:macro public static function dO(body : Expr) return // the function to trigger the Monad macro.
    Monad.dO("mypackage.OptionM", body, Context)

  inline public static function ret<T>(x : T) return // creates an element
    Some(x)
  
  inline public static function map < T, U > (x : Option<T>, f : T -> U) : Option<U> {
    switch (x) {
      case Some(x) : return Some(f(x));
      default : return None;
    }
  }

  inline public static function flatMap<T, U>(x : Option<T>, f : T -> Option<U>) : Option<U> {
    switch (x) {
      case Some(x) : return f(x);
      default : return None;
    }
  }
}


Using a Monad instance (Option here).


        OptionM.dO({
          value <= ret(55);
          value1 <= ret(value * 2);
          ret(value1 + value);
        });

Due to optimisations; this code reduce to Some(165), those optimisations are applied by default.
One can define his own optimisations (feeding the Monad.dO method its last parameter)


  @:macro public static function dO(body : Expr) return
    Monad.dO("mypackage.OptionM", body, Context, myCustomTransformation)

(please refer to the default function code to make sense of how to make optimization – macro knowledge requiered).

or using no optimisation at all:


  @:macro public static function dO(body : Expr) return
    Monad.dO("mypackage.OptionM", body, Context, Monad.noOpt)

Syntactic Sugar support.

Monax provides some leaner syntax:


import com.mindrocks.monads.Monad.dO in Do; ... Do({ value <= [55]; value1 <= return value * 2; return value1 + value; });

monax's People

Contributors

sledorze avatar marcweber avatar dogles avatar joemukai avatar deltaluca avatar m22spencer avatar

Stargazers

Daniel Rodríguez Rivero avatar Sylvio Sell avatar Tomas Slusny avatar Pavel Shuvaev avatar Laurence Dougal Myers avatar g. nicholas d'andrea avatar Mark Chadwick avatar Alfredo Di Napoli avatar Andre Pang avatar Brennan Kinney avatar paling avatar Charles Strahan avatar Dario Elyasy avatar Tom Link avatar Alexander Gordeyko avatar  avatar Quil avatar  avatar Justin Donaldson avatar Simon Richardson avatar s.murayama avatar Nathan Sorenson avatar  avatar Jonas Malaco avatar Ronan Sandford avatar James Jackson avatar Giorgio Arata avatar Ritchie Turner avatar  avatar 70/V9 avatar Damian Clark avatar francesco agati avatar Daichi Shinozaki avatar Brad Jones avatar

Watchers

paling avatar  avatar SwhGo_oN avatar James Cloos avatar  avatar Simon Richardson avatar

monax's Issues

Can a monad have a type parameter

Hi,

I have already asked a related question in the haxe mailing list.

I would like to write a monad for a Surprise from tink_core. I have done this assuming "Failure=String" like this:

  inline public static function flatMap<T, U>(x : Surprise<T,String>, f : T -> (Surprise<U,String>)) : Surprise<U,String> {
    return x.flatMap(function(t) {
      return switch(t) {
        case Failure(s):
          Future.sync(Failure(s));
        case Success(v):
          f(v);
        }
    });
  }

So it gets the first surprise (x), and than executes f only if the result is a success. Otherwise it directly returns the failure.

Now I want to generalize this and make a "MonadSurprise" where F denotes the type of the Failure.

But I am failing because I cannot write:

public static function monad<T>(f : Surprise<T, F>) return
MonadSurprise<F>;

According to the thread I already started it might be ok if "monad" just returns a instance of "MonadSurprise" and all "flatMap" and similar are made non-static.

But I do not know how to write the "dO" function. Maybe like this:

  macro public static function dO<F2>(body : Expr) return // the function to trigger the Monad macro.
    Monad._dO("monads.MonadSurprise<" + Type.getClassName(F2) + ">", body, Context);

But, when calling it like this:

 MonadSurprise.dO<Error>({
    ...
});

I get:

Error:(42, 4) Macro functions must be called immediately

nodejs monad is called two time with haxe timer delay

Hi,
i have try to modify the nodejs monad in test example for simulate async function with haxe timer delay. It work fine but the function with the trace is calling two times.

Here the code. I've tested the compiled js on safari browser

import com.mindrocks.monads.instances.Prelude;

import com.mindrocks.monads.Monad;
import com.mindrocks.monads.instances.NodeJs;


using com.mindrocks.monads.instances.Prelude;


class Obj {
  var name : String;
  public function new(name : String) {    
    this.name = name;
  }
}

class Collection {
  var objs : Array<Obj>;
  public function new() { 
    objs = [new Obj("a"), new Obj("b")];
  }
  public function all(name : Dynamic, cb : Error -> Array<Obj> -> Void) {    
    // cb("Aieeeuu!!", null);
    haxe.Timer.delay(function() {
      cb(null, objs);
    }, 1000);

  }
}

class DB {
  var coll : Collection;
  public function new() {
    coll = new Collection();
  }
  public function collection(name : String, cb : Error -> Collection -> Void) {

    haxe.Timer.delay(function() {
      cb(null, coll);
    }, 1000);

  }
}


class Main {

  public static function main(){

    var db = new DB();    
     var res5 : String = "";

     NodeM.dO({
       coll <= db.collection("avatars", _);
       avatars <= coll.all("ssss", _);
       ret(avatars.length);
     })(function (err, res) trace(res));


  }

}





flash + MonadOp not found.

I searched mailing list first and found a short discussion on fixing this, but doesn't seem anything came about;

I've solved it locally by adding: #if flash MEmpty; #end to MonadOp and prevent it becoming an empty enum in flash.

Error in readme

import com.mindrocks.Monad.dO => dO; causes:

Unexpected =>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.