さめたコーヒー

kbaba1001's blog.

SanctuaryJSのメモ

github.com

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 を使いたいだけならこっちのほうが楽かも

github.com