質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

関数型プログラミング

関数型プログラミングとは、関数を用いて演算子を構築し、算出し、コンピュータプログラムを構成する枠組みです。

Q&A

2回答

313閲覧

この書き方は合ってますか?

退会済みユーザー

退会済みユーザー

総合スコア0

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

関数型プログラミング

関数型プログラミングとは、関数を用いて演算子を構築し、算出し、コンピュータプログラムを構成する枠組みです。

0グッド

0クリップ

投稿2017/10/11 18:00

編集2017/10/11 18:33

JavaScript

1const sum = (list) => list.reduce((accumulator, item) => { return accumulator + item }, 0); 2 3const multiplyBy = (byHowMuch) => (list) => list.map((item) => item * byHowMuch); 4 5const isLargerThan = (value) => (comparedValue) => comparedValue > value; 6 7const displayLog = (value) => { console.log(value) }; 8 9const compose = (log, compare, sum, multiplyBy) => (list) => log(compare(sum(multiplyBy(list)))); 10 11// trueが期待通りに出力されます。動作確認済み。 12compose(displayLog, isLargerThan(10), sum, multiplyBy(10))([1, 2, 3, 4, 5]);

カーリー化や関数合成が本を読んだだけでは身につかなさすぎるので、コードを実際に書いてみようと思って書いてみたのですが、関数型プログラミングっぽくなってますでしょうか?コード自体は動作確認済みなので動きますが。(単なる練習で書いたので実用的では全くないです。。。)

const compose = (log, compare, sum, multiplyBy) => (list) => log(compare(sum(multiplyBy(list))));

特に、この行の関数で他の関数の結果をラップしまくってるところとか、こんなことするんでしたっけ?

あと、例えば、10以上じゃない場合はdisplayLogを実行しないみたいなことをするには、どのようにすれば良いのでしょうか?

const displayLog = (value) => { value && console.log(value)};

例えばこんな感じで、単純に条件式を中で書くしかないですよね?条件式が複数、一つの関数内に出てきてしまうと手続き的になってしまうから好ましくないってだけであって、1つ出てくる分には当たり前??いや、引数に渡ってきた値によって処理を変えるのをその該当関数で判断させるのは、本来の仕事意外のことも担うことになるから好ましくない???

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

そもそも論ですが、JavaScriptでの関数型プログラミングは「まあ、できなくもないかな」という程度の話で、書きにくいし、関数型プログラミングの枠を簡単に逸脱できてしまいます。

本気で関数型を書きたいなら、PureScriptなど、専用のAltJSを使ったほうがいいと思います。

あと、

条件式が複数、一つの関数内に出てきてしまうと手続き的になってしまうから好ましくないってだけであって、1つ出てくる分には当たり前??いや、引数に渡ってきた値によって処理を変えるのをその該当関数で判断させるのは、本来の仕事意外のことも担うことになるから好ましくない???

このあたりの「処理の粒度」の話は、関数型プログラミングとは無関係です。純粋関数型でも、関数内で「引数だけに依存する」「再代入・破壊的変更が不可能な」変数を作って、処理を進めても問題ありません。

投稿2017/10/12 00:30

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/10/12 02:10

ご回答ありがとうございます!粒度の話は直接的に関係ないことなのですね。PureScriptか〜。人が絡むプロジェクトでは使えなさそうですけど、一度は使って勉強すれば得るものはあるはずなので、どこかで時間とって使ってみます!!
退会済みユーザー

退会済みユーザー

2017/10/12 02:22

関数型寄りのreactやreduxなど使う時って、どうしたらよいのでしょうか?oopとの併用ですか?関数型に寄せたほうが良いですか?
guest

0

JavaScript

1const sum = (list) => list.reduce((accumulator, item) => { return accumulator + item }, 0); 2const multiplyBy = (byHowMuch) => (list) => list.map((item) => item * byHowMuch); 3const isLargerThan = (value) => (comparedValue) => comparedValue value; 4const displayLog = (value) => { console.log(value) };

カリー化がちゃんと出来てないけど及第点
本物のカリー化はこれを満たす関数。

JavaScript

1// カリー化出来ている関数 2add(2, 3); // 5 3add(2)(3); // 5 4 5// カリー化出来ていない関数 6add(2, 3); // function

JavaScriptでは関数を宣言すると、fn.lengthに求める引数の数が入ってくる。
これと関数内に入ってきたargumentsを比較して必要数を満たすまで保留する関数を返すようにする必要がある。


JavaScript

1const compose = (log, compare, sum, multiplyBy) => (list) => log(compare(sum(multiplyBy(list))));

アウト、それじゃなんの柔軟性もないでしょ!
JavaScriptは関数内でargumentsが自動的に宣言されるのでそれを利用する
因みにアロー関数() => {}の場合はargumentsが宣言されずエラーになるから最初は意図的にfunctionを利用している。

JavaScript

1// 再帰バージョン 2let compose = function () { 3 const args = [].slice.call(arguments) 4 const initial = [].slice.call(arguments) 5 const last = initial.pop() 6 return (trigger) => 7 (args.length === 0) ? trigger : compose.apply(null, initial)(last(trigger)) 8} 9 10// for文バージョン 11let compose = function () { 12 const args = [].slice.call(arguments) 13 return (trigger) => { 14 for (let i = args.length - 1; i >= 0; i--) { 15 trigger = args[i](trigger) 16 } 17 return trigger 18 } 19} 20 21const add2 = (a) => a + 2 22const mul2 = (a) => a * 2 23 24compose(add2, mul2)(1) // 4 25compose(add2, mul2)(3) // 8 26compose(add2, add2, mul2)(3) // 10

素のJSは関数型プログラミングするには向いてない。
JS自体の言語仕様への理解も必要で、この程度の深さのコードがサラッと書けないと話にならないよ。
(ぶっちゃけ私も力不足をひしひしと感じているレベルだし)

この辺はmaisumakunさんの仰るとおりで、LiveScriptやPureScriptといったAltJSを使うのが最善。
それが叶えられないプロジェクトで仕方なくRamda.jsやLodash等のライブラリを併用する。

それでも素のJSだけで関数型プログラミングをやりたいなら、
多少遠回りしてでも関数型プログラミング用のライブラリを使い込んだ上で実装を読み込み、
JSと関数型プログラミングの折り合いをどう付けるのかを覚えなきゃダメだよ。

投稿2017/10/12 01:41

miyabi-sun

総合スコア21158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/10/12 02:09

ご回答ありがとうございます。あとで読み込ませて頂きます!reactやreduxなど関数型プログラミングを用いている(?)フレームワークの場合、それに合わせて関数型で書いたほうがいいのかなと思ってるのですが、どうなんでしょうね。。。OOPで行っていいのか、関数型に寄せた方がいいのかワケワカメです。は〜〜〜、なかなか霧がはれません。。。
退会済みユーザー

退会済みユーザー

2017/10/12 02:13

”””JavaScriptでは関数を宣言すると、fn.lengthに求める引数の数が入ってくる。 これと関数内に入ってきたargumentsを比較して必要数を満たすまで保留する関数を返すようにする必要がある。””” ↑ 仮引数と実引数を比較するということですよね!
退会済みユーザー

退会済みユーザー

2017/10/12 02:21 編集

// 再帰バージョンとforバージョンありがとうございました。 なるほど、動的に処理出来るようにするのですね。勉強になりました!!質問してよかった(涙)
退会済みユーザー

退会済みユーザー

2017/10/12 02:20

僕のはカーリー化になってませんでしたか?最後に実行する関数で必ず関数ではない値が返って くるようになってればカーリー化に成功してますか?
miyabi-sun

2017/10/12 02:23

``` const multiplyBy = (byHowMuch) => (list) => list.map((item) => item * byHowMuch) multiplyBy(1, 3) // fn ``` ここで3が帰ってくるのがカリー化 これは次の引数をくれという関数を返しているだけで2つの引数を処理してくれないからカリー化されてるわけじゃないよ
miyabi-sun

2017/10/12 02:30 編集

react、reduxは確かに関数型プログラミング的なライブラリだけど、 それ言ったらjQueryだってHaskellのモナドに酷似した関数型プログラミング的なライブラリと見なせるんだよ? でもjQueryで関数型プログラミングしてるエンジニア見たことある? …つまりそういうことよ。 reduxは関数くれたらそれで動くって言ってるんだから、 その中は別に命令形プログラミングだろうがオブジェクト指向プログラミングだろうが動くわけだよね。 関数型プログラミングにするメリットは、副作用のない処理を関数に追い出して単体テスト出来る所にしかない。 そして残った副作用はreduxに渡す直前の関数に凝縮されるわけで、 憂鬱な結合テストがなくなるわけじゃないしね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問