はじめに
カリー化を理解しようとサンプルを考えていたら、パイプライン演算子もどきの関数を思いついたので紹介します
パイプライン演算子とは
最近お気に入りのjuliaという言語では関数を連鎖的に実行してくれるパイプライン演算子という構文があります
juliaの例
const HALFWIDEDIFF = 'a' - 'a'
function toWideChar(str::String)
return replace(str, r"[a-zA-Z0-9]" => x -> Char(codepoint(x[1]) + HALFWIDEDIFF))
end
function toHalfChar(str::String)
return replace(str, r"[A-Za-z0-9]" => x -> Char(codepoint(x[1]) - HALFWIDEDIFF))
end
s = " hello " |>
strip |> #両端の空白を削除
uppercase |> #大文字
toWideChar #全角
println(s) #HELLO
javascriptでは
末尾の()は連鎖の終了を判定させるために必要です
出来ればつけなくて良いようにしたいのですが、良い方法は思いつきませんでした
const HALFWIDEDIFF = "a".charCodeAt(0) - "a".charCodeAt(0);
function toWideChar(str) {
return str.replace(/[a-zA-Z0-9]/g, x => String.fromCharCode(x.charCodeAt(0) + HALFWIDEDIFF));
}
function toHalfChar(str) {
return str.replace(/[A-Za-z0-9]/g, x => String.fromCharCode(x.charCodeAt(0) - HALFWIDEDIFF));
}
const trim = x => x.trim()
const toUpperCase = x => x.toUpperCase()
function pipeFunc(value) {
return function (func = null) { return func ? pipeFunc(func(value)) : value};
};
const s = pipeFunc(" hello ")
(trim) // (x => x.trim()) でもok
(toUpperCase) // (x => x.toUpperCase()) でもok
(toWideChar)()
console.log(s) //HELLO
typescript
function pipeFunc(value: any): Function {
return function (func?: Function): any { return func ? pipeFunc(func(value)) : value};
}
類似の方法
参考までに、reduceを使った類似の方法も思いついたので紹介します
function pipeFuncs(initialValue, ...funcs) {
return funcs.reduce((value, currentFunc) => currentFunc(value), initialValue);
}
const str = pipeFuncs(" hello "
, trim // x => x.trim() でもok
, toUpperCase // x => x.toUpperCase() でもok
, toWideChar
)
console.log(str) //HELLO
typescript
function pipeFuncs(initialValue: any, ...funcs: Function[]): any {
return funcs.reduce((value, currentFunc) => currentFunc(value), initialValue);
}