commit 615d427fa892cbeea760ab88df3cd3489ac366d3 Author: Correl Roush Date: Thu Apr 24 00:47:45 2014 -0400 Maybe diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d14ac60 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +deps +*.sublime-project +*.sublime-workspace +*.beam +.eunit +debug-* +ebin/* +bin/expm +*.dump +.rebar diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..8a45231 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +language: erlang +script: "make check-travis" +notifications: + #irc: "irc.freenode.org#YOUR-PROJECT-CHANNEL" + recipients: + #- YOU@YOUR.DOMAIN +otp_release: + - R16B03 + - R15B03 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..31ea6a8 --- /dev/null +++ b/Makefile @@ -0,0 +1 @@ +include common.mk diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..47c976f --- /dev/null +++ b/README.rst @@ -0,0 +1,55 @@ +########### +maybe +########### + + +Introduction +============ + +Add content to me here! + + +Dependencies +------------ + +This project assumes that you have `rebar`_ installed somwhere in your +``$PATH``. + +This project depends upon the following, which are installed to the ``deps`` +directory of this project when you run ``make deps``: + +* `LFE`_ (Lisp Flavored Erlang; needed only to compile) +* `lfeunit`_ (needed only to run the unit tests) + + +Installation +============ + +Just add it to your ``rebar.config`` deps: + +.. code:: erlang + + {deps, [ + ... + {maybe, ".*", {git, "git@github.com:YOURNAME/maybe.git", "master"}} + ]}. + + +And then do the usual: + +.. code:: bash + + $ rebar get-deps + $ rebar compile + + +Usage +===== + +Add content to me here! + +.. Links +.. ----- +.. _rebar: https://github.com/rebar/rebar +.. _LFE: https://github.com/rvirding/lfe +.. _lfeunit: https://github.com/lfe/lfeunit diff --git a/common.mk b/common.mk new file mode 100644 index 0000000..2f8a762 --- /dev/null +++ b/common.mk @@ -0,0 +1,107 @@ +PROJECT = maybe +LIB = $(PROJECT) +DEPS = ./deps +BIN_DIR = ./bin +EXPM = $(BIN_DIR)/expm +LFETOOL=$(BIN_DIR)/lfetool +SOURCE_DIR = ./src +OUT_DIR = ./ebin +TEST_DIR = ./test +TEST_OUT_DIR = ./.eunit +SCRIPT_PATH=.:./bin:$(PATH):/usr/local/bin + +$(BIN_DIR): + mkdir -p $(BIN_DIR) + +$(LFETOOL): $(BIN_DIR) + @[ -f $(LFETOOL) ] || \ + curl -o ./lfetool https://raw.github.com/lfe/lfetool/master/lfetool && \ + chmod 755 ./lfetool && \ + mv ./lfetool $(BIN_DIR) + +get-version: + @PATH=$(SCRIPT_PATH) lfetool info version + +$(EXPM): $(BIN_DIR) + @[ -f $(EXPM) ] || \ + PATH=$(SCRIPT_PATH) lfetool install expm $(BIN_DIR) + +get-deps: + @echo "Getting dependencies ..." + @rebar get-deps + @PATH=$(SCRIPT_PATH) lfetool update deps + +clean-ebin: + @echo "Cleaning ebin dir ..." + @rm -f $(OUT_DIR)/*.beam + +clean-eunit: + @PATH=$(SCRIPT_PATH) lfetool tests clean + +compile: get-deps clean-ebin + @echo "Compiling project code and dependencies ..." + @rebar compile + +compile-no-deps: clean-ebin + @echo "Compiling only project code ..." + @rebar compile skip_deps=true + +compile-tests: + @PATH=$(SCRIPT_PATH) lfetool tests build + +shell: compile + @clear + @echo "Starting shell ..." + @PATH=$(SCRIPT_PATH) lfetool repl lfe + +shell-no-deps: compile-no-deps + @clear + @echo "Starting shell ..." + @PATH=$(SCRIPT_PATH) lfetool repl + +clean: clean-ebin clean-eunit + @rebar clean + +check-unit-only: + @PATH=$(SCRIPT_PATH) lfetool tests unit + +check-integration-only: + @PATH=$(SCRIPT_PATH) lfetool tests integration + +check-system-only: + @PATH=$(SCRIPT_PATH) lfetool tests system + +check-unit-with-deps: get-deps compile compile-tests check-unit-only +check-unit: compile-no-deps check-unit-only +check-integration: compile check-integration-only +check-system: compile check-system-only +check-all-with-deps: compile check-unit-only check-integration-only \ + check-system-only +check-all: get-deps compile-no-deps + @PATH=$(SCRIPT_PATH) lfetool tests all + +check: check-unit-with-deps + +check-travis: $(LFETOOL) check + +push-all: + @echo "Pusing code to github ..." + git push --all + git push upstream --all + git push --tags + git push upstream --tags + +install: compile + @echo "Installing maybe ..." + @PATH=$(SCRIPT_PATH) lfetool install lfe + +upload: $(EXPM) get-version + @echo "Preparing to upload maybe ..." + @echo + @echo "Package file:" + @echo + @cat package.exs + @echo + @echo "Continue with upload? " + @read + $(EXPM) publish diff --git a/include/maybe.lfe b/include/maybe.lfe new file mode 100644 index 0000000..a1433c8 --- /dev/null +++ b/include/maybe.lfe @@ -0,0 +1,2 @@ +(defmacro do statements + (maybe:do-statement statements)) \ No newline at end of file diff --git a/include/maybe.lfe~ b/include/maybe.lfe~ new file mode 100644 index 0000000..57c814b --- /dev/null +++ b/include/maybe.lfe~ @@ -0,0 +1,2 @@ +(defmacro do statements + `(maybe:do-statement ',statements)) \ No newline at end of file diff --git a/package.exs b/package.exs new file mode 100644 index 0000000..ba4de12 --- /dev/null +++ b/package.exs @@ -0,0 +1,7 @@ +Expm.Package.new( + name: "maybe", + description: "maybe DESCRIPTION", + version: "0.0.1", + keywords: ["LFE", "Lisp", "Library", "API"], + maintainers: [[name: "YOUR NAME", email: "YOUR@EMAIL.com"]], + repositories: [[github: "YOUR_GITHUB_NAME/maybe]]) diff --git a/rebar.config b/rebar.config new file mode 100644 index 0000000..bb7d547 --- /dev/null +++ b/rebar.config @@ -0,0 +1,20 @@ +{erl_opts, [debug_info, {src_dirs, ["test/unit", + "test/integration", + "test/system"]}]}. +{lfe_first_files, []}. +{deps_dir, ["deps"]}. +{plugins, ['lfe-sample-rebar-plugin']}. +{eunit_compile_opts, [ + {src_dirs, ["test/unit", + "test/integration", + "test/system", + "src"]} + ]}. +{deps, [ + {lfe, ".*", {git, "git://github.com/rvirding/lfe.git", "develop"}}, + {'lfe-utils', ".*", {git, "https://github.com/lfe/lfe-utils.git", "master"}}, + {lfeunit, ".*", {git, "git://github.com/lfe/lfeunit.git", "master"}}, + {'lfe-sample-rebar-plugin', + ".*", {git, "git://github.com/oubiwann/lfe-sample-rebar-plugin.git", + "master"}} + ]}. diff --git a/src/maybe.app.src b/src/maybe.app.src new file mode 100644 index 0000000..6685cfe --- /dev/null +++ b/src/maybe.app.src @@ -0,0 +1,37 @@ +%% -*- erlang -*- +{application, 'maybe', + [ + %% A quick description of the application. + {description, "My project description..."}, + + %% The version of the application + {vsn, "0.0.1"}, + + %% All modules used by the application. + {modules, + [ + 'maybe' + ]}, + + %% All of the registered names the application uses. This can be ignored. + {registered, []}, + + %% Applications that are to be started prior to this one. This can be ignored + %% leave it alone unless you understand it well and let the .rel files in + %% your release handle this. + {applications, + [ + kernel, + stdlib + ]}, + + %% OTP application loader will load, but not start, included apps. Again + %% this can be ignored as well. To load but not start an application it + %% is easier to include it in the .rel file followed by the atom 'none' + {included_applications, []}, + + %% configuration parameters similar to those in the config file specified + %% on the command line. can be fetched with gas:get_env + {env, []} + ] +}. \ No newline at end of file diff --git a/src/maybe.lfe b/src/maybe.lfe new file mode 100644 index 0000000..fecdc0d --- /dev/null +++ b/src/maybe.lfe @@ -0,0 +1,31 @@ +(defmodule maybe + (export all)) + +(defun my-adder (x y) + (+ x (+ y 1))) + +(defun >>= + (('nothing f) + 'nothing) + (((tuple 'just x) f) + (funcall f x))) + +(defun >> (a b) + (>>= a (lambda (_) b))) + +(defun return (x) (tuple 'just x)) +(defun fail (_) 'nothing) + +;; (defmacro do statements +;; `(lists:foldl >>= (car statements) (cdr statements))) + + ;; (defmacro do statements + ;; `'(list ,@statements)) + +(defun do-statement + (((cons h '())) h) + (((cons (list f '<- m) t)) (list ': 'maybe '>>= + m + (list 'lambda (list f) (do-statement t)))) + (((cons h t)) (list 'lambda '(_) (do-statement t))) + ) diff --git a/test/unit/unit-maybe-tests.lfe b/test/unit/unit-maybe-tests.lfe new file mode 100644 index 0000000..29cd57b --- /dev/null +++ b/test/unit/unit-maybe-tests.lfe @@ -0,0 +1,44 @@ +(defmodule unit-maybe-tests + (export all) + (import + (from lfeunit-util + (check-failed-assert 2) + (check-wrong-assert-exception 2)))) + +(include-lib "deps/lfeunit/include/lfeunit-macros.lfe") +(include-lib "include/maybe.lfe") + +(deftest bind-nothing + (is-equal 'nothing + (maybe:>>= 'nothing + (lambda (x) (+ 5 x))))) + +(deftest bind-nothing-error + (is-equal 'nothing + (maybe:>>= 'nothing + (lambda (_) (error 'bad-func))))) + +(deftest bind-five + (is-equal 10 + (maybe:>>= (tuple 'just 5) + (lambda (x) (+ 5 x))))) + +(deftest bind-fold + (is-equal #(just 3) + (let ((minc (lambda (x) (maybe:return (+ 1 x)))) + (bind (lambda (f m) (maybe:>>= m f)))) + (lists:foldr bind + #(just 0) + (list minc + minc + minc))))) + +(deftest >> + (is-equal #(just 3) + (maybe:>> #(just 5) #(just 3)))) + +(deftest do + (is-equal #(just 3) + (do (a <- #(just 1)) + (b <- #(just 2)) + (maybe:return (+ a b))))) \ No newline at end of file