Giter Site home page Giter Site logo

akimichi / functionaljs Goto Github PK

View Code? Open in Web Editor NEW
39.0 4.0 8.0 7.17 MB

「関数型プログラミングの基礎」サンプルコード

Home Page: http://akimichi.github.io/functionaljs/

License: MIT License

JavaScript 97.13% CoffeeScript 0.05% Ruby 0.36% Scala 1.28% Haskell 0.20% Shell 0.07% HTML 0.18% Dockerfile 0.74%
javascript nodejs functional-programming

functionaljs's Introduction

「関数型プログラミングの基礎」サンプルコード

このレポジトリは、リックテレコム社刊行の「関数型プログラミングの基礎」のサンプルコードをおさめたものです。

github pagesのサイトは、http://akimichi.github.io/functionaljs/ になります。

利用法

サンプルコードを利用するには、まず最初に本レポジトリをクローンし、次にそのディレクトリに入ります。

$ git clone [email protected]:akimichi/functionaljs.git
$ cd functionaljs

テスト環境の構築には、 1) 個別にインストールする, 2) docker を使う 、 の2つの方法があります。

ローカル環境にテスト環境を個別にインストールする

ここでは ubuntu が動作している環境にテスト環境をインストールする方法を説明します。 他のOSについては、書籍を参照ください。

node.js のインストール

node.jsのインストールは、nvmを用います。

nvmをインストールするには、curlコマンドを用いて次のようにするのが簡便です。

$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.32.0/install.sh | bash

あるいはwgetコマンドを用いる場合は、次のようになります。

$ wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.32.0/install.sh | bash

上記の方法はスクリプトが移動したなどの理由で失敗することがあります。 もしインストールに失敗する場合は、https://github.com/creationix/nvm を参考にして最新の方法でインストールしてください。

次に、node.js v0.12.0 をインストールします。

$ nvm install v0.12.0

テストの実行

ローカル環境に nvm がインストールされていることが必要です。

レポジトリをクローンしたディレクトリに移動します。

cd functionajs

nvm use で node.jsのバージョン v0.12.0 を使うことを指定します。 npm install で必要なパッケージをインストールします。

$ nvm use
$ npm install

テストを実行するには gulp を利用します。 gulpコマンドを利用するため、以下のようにgulpをグローバルにインストールします。

$ npm install -g gulp

これでJavaScriptのコードをテストする準備が整いました。 コードのテストは、以下のようにします。

$ gulp js-test

なおscalaとhaskellのコードをテストするには、以下のdockerによるインストールを参照ください。

dockerを使う

dockerを使って、各種のテスト環境を構築できます。 あらかじめdockerをインストールしておいてください。 この方法は、dockerさえインストールしておけば確実に環境を構築できるという利点があります。 ただし、dockerイメージは約4GBあるのでディスク容量の少ないマシンでの利用には注意してください。

なお、dockerを使ったインストールは、リックテレコム社が推奨する方法ではありません。 インストール時の問題等のついては、 https://github.com/akimichi/functionaljs/issues に投稿してください。

dockerイメージを準備する

dockerコンテナを動かす前に、dockerイメージを準備する必要があります。 dockerイメージを取得するには、2つの方法があります。 ひとつは docker hub からダウンロードする方法で、もうひとつはDockerfileから自分で作成する方法です。

docker hubから取得する

docker hubからイメージをダウンロードするには、pullコマンドを利用します。

$ docker pull emile/functionaljs:v1
dockerのイメージを自分で作成する

イメージを準備するもう一つの方法は、Dockerfileをもとに自分でdockerイメージを作成する方法です。 イメージをローカル環境に作成するには、dockerコマンドで以下のようにします。

$ docker build -t="username/functionaljs:v1" .

なお、上記コマンドのusernameには基本的にユーザー名がはいります。

単体テストを実行する

dockerイメージが準備できれば、そのイメージからコンテナを起動することでテストの実行が可能です。

以下のコマンドでnode.jsのコードをテストします。 もし自分のユーザー名でイメージを作成した場合は、以下のemileの箇所を、そのユーザー名に置きかえてください。

$ docker run -it --rm --workdir="/workspace/nodejs" emile/functionaljs:v1 /bin/bash --login -i -c "gulp --harmony js-test"

以下のコマンドでscala のコードをテストします。

$ docker run -it --rm --workdir="/workspace/scala" emile/functionaljs:v1 /bin/bash -c "sbt test"

以下のコマンドでhaskell のコードをテストします。

$ docker run -it --rm  --workdir="/workspace/haskell" emile/functionaljs:v1 /bin/bash -c "stack test"

REPLを実行する

dockerコンテナにログインすることで、node.jsなどの対話的環境(REPL)を実行できます。

REPL を実行するには、まずコンテナにログインします。

$ docker run -it  --workdir="/workspace" emile/functionaljs:v1 bash --login -i

これでコンテナ内の /workspace ディレクトリにログインしました。

node.jsのREPLを試すには、以下のように nodejsのディレクトリに移動して nodeコマンド を呼びだします。 コンソールを抜けるときは Ctrl-C を2回続けて押します。

$ cd nodejs/
$ node
> 1 + 2
3
> 
(^C again to quit)

scala のREPLを試すには、 scalaのディレクトリに移動して、 sbt console を起動します。 コンソールを抜けるには、:q を入力します。

$ cd scala
$ sbt console

[info] Loading project definition from /workspace/scala/project
[info] Set current project to Functional Book Test Project (in build file:/workspace/scala/)
[info] Starting scala interpreter...
[info] 
Welcome to Scala version 2.9.1.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_80).
Type in expressions to have them evaluated.
Type :help for more information.

scala> 1 + 2
res0: Int = 3

scala> :q

haskellのREPLを試すには、 haskell のディレクトリに移動して、 ghci を起動します。 コンソールを抜けるには、:q を入力します。

$ cd haskell
$ ghci

GHCi, version 7.10.2: http://www.haskell.org/ghc/  :? for help
Prelude> 1 + 2
3
Prelude> :q
Leaving GHCi.

functionaljs's People

Contributors

akimichi avatar moco7 avatar

Stargazers

fuqda avatar takemura avatar  avatar  avatar  avatar takeuchi avatar  avatar Rintaro Itokawa avatar  avatar s.habata avatar Masahiro Yokoyama avatar smapira avatar  avatar Takashi Hiragi avatar Hirotaka Tagawa / wafuwafu13 avatar  avatar kumi avatar Katsunori Kanda avatar yoshimoto koki avatar Takuya avatar ASID avatar  avatar Kotaro Sugawara avatar Akihiro Kubota avatar Akiyoshi Hanai avatar 70_10 avatar t.kuriyama avatar tadaken3 avatar tanagumo avatar hiroshiro avatar Kodai Nakamura avatar mkwtys avatar Ryo Oshima avatar yT avatar Chun-Hao Lien avatar U-Yeong Ju avatar Yoshida avatar cybai (Haku) avatar azu avatar

Watchers

 avatar James Cloos avatar  avatar Takuya avatar

functionaljs's Issues

Wrong flatMap definition? (without world version)

You define IO.flatMap as below. (https://github.com/akimichi/functionaljs/blob/master/bin/io_without_world.js#L48-L53)

flatMap: (instanceA) => {
  var self = this;
  return (actionAB) => { // actionAB:: a -> IO b
    return self.unit(self.run(actionAB(self.run(instanceA))));
  };
}

But this definition evaluates self.run(actionAB(self.run(instanceA)) eagerly.
For example, the code below displays hello monad before executing IO.run(e).

// putStr :: String => IO[Unit]
const putStr = (s) => IO.flatMap(IO.unit(s))((s) => {
  console.log(s);
  return IO.unit();
});
const e = putStr('hello monad'); // display 'hello monad' at this point
IO.run(e); // shoud be displayed at this point

So I think the definition should be as below.

flatMap: (instanceA) => {
  const self = this;
  return (actionAB) => { // actionAB:: a -> IO b
    return () => self.run(actionAB(self.run(instanceA)))
  };
}

https://github.com/akimichi/functionaljs/blob/master/bin/io_without_world.js#L48-L53
にて、IO.flatMapは以下のように定義されています。

flatMap: (instanceA) => {
  var self = this;
  return (actionAB) => { // actionAB:: a -> IO b
    return self.unit(self.run(actionAB(self.run(instanceA))));
  };
}

しかし、この定義ではself.run(actionAB(self.run(instanceA))を正格評価してしまうと思います。
(正格評価という表現が適切か分かりませんが、IO.flatMap(instanceA)(actionAB)の時点で評価されます。)
例えば、以下のコードではIO.run(e)の実行前にhello monadが表示されます。

// putStr :: String => IO[Unit]
const putStr = (s) => IO.flatMap(IO.unit(s))((s) => {
  console.log(s);
  return IO.unit();
});
const e = putStr('hello monad'); // この時点で'hello monad'が表示されます
IO.run(e); // 実際には、この時点で表示されるべきかと思います

そのため、flatMapの定義としては以下のほうが適切かと思いますが如何でしょうか。

flatMap: (instanceA) => {
  const self = this;
  return (actionAB) => { // actionAB:: a -> IO b
    return () => self.run(actionAB(self.run(instanceA)))
  };
}

よろしくお願いします。

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.