はじめに
checkForFactor :: Int -> Int -> Bool
checkForFactor = (.) (== 0) . mod
これをなんとか理解しました。
でも、微妙に納得いってない部分があったんですよね。
その答えがわかったので追記する形です。
問題
checkForFactor :: Int -> Int -> Bool
checkForFactor x y = (.) (== 0) (mod x) y
これが原型です。
-
mod xでカリー化した1引数関数(定数xを割る、引数yの関数)を返す。 - 1の関数を、
(== 0)と関数合成。 - これで、
yを受け取る→mod xによりx % yが計算され、(== 0)に渡される→真偽値が返る、という関数が作れました!
問題は、ここからの変形です。
前の記事ではごちゃごちゃ書きましたが……
解決方法
yの削除
checkForFactor x y = (.) (== 0) (mod x) y -- 1
checkForFactor x = (.) (== 0) (mod x) -- 2
まずは基礎的にf x y = (.) g (h x) yの時、f x = (.) g (h x)です。
1の式checkForFactor x y = (.) (== 0) (mod x) yはつまりf x y = (.) g (h x) yなので、
2のcheckForFactor x = (.) (== 0) (mod x)に変形できます。
xの削除←ごちゃついたところ
checkForFactor x = (.) (== 0) (mod x) -- 2
checkForFactor x = ((.) (== 0)) (mod x) -- 3
checkForFactor = ((.) (== 0)) . mod -- 4
checkForFactor = (.) (== 0) . mod -- 5
まず、2を3に変形します。
すると、f x = g (h x)の形になります。
f x = g (h x)のとき、f = g . hのため、
3から4
checkForFactor = ((.) (== 0)) . modが成り立つのです!!
あとは、余分な()を取り除いて、
5のcheckForFactor = (.) (== 0) . modが導けます。
挙動は
-
xを部分適用し、mod xが生成される。 -
mod xは(.) (== 0)と合成され、「新しい関数」が生成される。 - 「新しい関数」は引数
yを受け取り、x `mod` yの結果が0かどうか判定する。
終わりに
ChatGPT先生と協力して、Javascriptでコードを書いてみました。
checkForFactor = (.) (== 0) . modのロジック・挙動を模倣したものです。
//mod
function mod(x) {
return function (y) {
return x % y;
}
}
//(.) (== 0)
function dotEqZero(f) {
return function (x) {
return f(x) === 0;
}
}
//checkForFactor = (.) (== 0) . mod
function checkForFactor(x) {
return dotEqZero(mod(x))
}
checkForFactor(x)(y)
もやもやがすっきりするの、キモチイイ……
またひとつ強くなってしまった……( •´ω•` )ﻭカンチガイジャナイヨネ?
まあ、すぐ壁にぶつかるんですけどね。
ばらかもんのなるを思い出しますね。
「僕最強。見るものすべてが美しい」状態と、「えっ知らない無理無理 Σ(OωO )」を繰り返すんだと思います、きっと。
