JavaScript で関数型言語っぽいコードを書けるようにするためのライブラリ
utils/sanctuary.js
とりあえず動かすための設定。
import { create, env } from 'sanctuary'; const S = create({ checkTypes: process.env.NODE_ENV !== 'production', env: env }); export default S;
これを import S from '../utils/sanctuary.js'
みたいにして使う
map
https://github.com/sanctuary-js/sanctuary#map--functorf--a-b---fa---fb
S.map (Math.sqrt) ([1, 4, 9])
Objectに対する map
S.map(([k, v]) => [v, k])(Object.entries({ a: 1, b: 2 }))
reduce
https://github.com/sanctuary-js/sanctuary#reduce--foldablef--b-a-b---b---fa---b
S.reduce (S.add) (0) ([1, 2, 3, 4, 5])
append (conj), prepend(cons)
https://github.com/sanctuary-js/sanctuary#append--applicativefsemigroupfa--a---fa---fa https://github.com/sanctuary-js/sanctuary#prepend--applicativefsemigroupfa--a---fa---fa
> S.append (3) ([1, 2]) [1, 2, 3] > S.prepend (1) ([2, 3]) [1, 2, 3]
pipe
https://github.com/sanctuary-js/sanctuary#pipe--foldablef--fany-any---a---b
関数を合成して実行する
> S.pipe ([S.add (1), Math.sqrt, S.sub (1)]) (99) 9
pipeK
https://github.com/sanctuary-js/sanctuary#pipek--foldablefchainm--fany-many---ma---mb
複雑な条件分岐を伴う処理を関数で書きたいときに maybe モナドや either モナドを使って実装すると楽な時がある。 pipeKを使うとモナドに対して関数合成をいい感じにやることができる。 例えば maybe モナド の場合、
S.fromMaybe("none")( S.pipeK([ v => (S.size(v) <= 0 ? S.Nothing : S.Just(v)), v => S.Just(S.filter(S.odd)(v)), ])(S.Just([1, 2, 3])) ) //=> [1,3] S.fromMaybe("none")( S.pipeK([ v => (S.size(v) <= 0 ? S.Nothing : S.Just(v)), v => S.Just(S.filter(S.odd)(v)), //上の関数が S.Nothing を返すのでここは実行されない ])(S.Just([])) ) //=> "none"
同様に either モナド の場合、
S.either(x => x)(x => x)( S.pipeK([ v => (S.size(v) <= 0 ? S.Left("none") : S.Right(v)), v => S.Right(S.filter(S.odd)(v)), ])(S.Right([1, 2, 3])) ) //=> [1, 3] S.either(x => x)(x => x)( S.pipeK([ v => (S.size(v) <= 0 ? S.Left("none") : S.Right(v)), v => S.Right(S.filter(S.odd)(v)), ])(S.Right([])) ) //=> "none"
either モナドは異常系をLeft、正常系をRightに入れる。
maybeモナドと異なり異常系のときに値を取ることができ、それを S.either
の第1引数で処理できる。
追記
単に monad を使いたいだけならこっちのほうが楽かも