FP(Functional Programming) - Reader


Reader monad


運転しながらの読み出し状態(config)

const config = {conf: true}
function fn1(){...}
function fn2(){
	if(config.conf) ...
}

이렇게 되면 함수의 순수성도 깨지게 되고, 코드가 길어지고 많아지면 코드 파악이 쉽지 않고
결과적으로 실수가 발생 할 수 있습니다. 

함수를 mapping 하면서 필요 할 때 가져다가 읽어오는 기능을 갖는게 Reader 모나드 입니다.

リーダ端子



mapやchainは実際にmayberと大きく異なるが,askという特殊な関数がある.
この関数を使用すると、入力した設定を取得し、次のマッピング関数のパラメータに渡すことができます.

Reader Monadの実装



runReader関数は、作成時に入力する関数です.最初にreader monadを作成したときにパラメータがなかったため、envを受け入れてTタイプの値を返します.つながっている.
map関数はenvを受信してマッピングされた関数を登録し、対応する母題のrunReaderと合成して返される関数を新しい母題のrunReader関数とする.
ask関数はidentity関数を登録します.envを入力すると、envが値を返す可能性があると推測できます.
言葉で説明するのは複雑すぎる.ううう
runReader : () => 10 // 시작 
map f: v => v + 10 ~> runReader((env)=> f(()=>10));
map g: v => v + 20 -> runReader((env) => g((env) => f(() => 10)));

이런식으로 reader 모나드를 생성하면서 전에 있던 reader 모나드의 
runReader를 합성 합니다. 여기서 runReader(99) 을 호출 하게 되면 아래와 같이 실행 됩니다.

runRader((99) => g((99) => f(() => 10))); 시작 함수의 리턴값
runReader((99) => g((99) => 20); 
runReader((99) => g(20);
runReader(40); 

다시 코드를 보면
runReader : () => 10 // 시작 
map f: v(10) => v + 10 ~> runReader((99)=> f(()=>10));
map g: v(20) => v + 20 -> runReader((99) => g((99) => f(() => 10)));

이렇게 mapping 함수의 리턴값이 다음 map 함수의 파라미터로 연계가 됩니다.

ask 함수를 한번 보겠습니다.

runReader : () => 10 // 시작 
map f: v(10) => v + 10 ~> runReader((99)=> f(()=>10));
map g: v(20) => v + 20 -> runReader((99) => g((99) => f(() => 10)));
ask() -> id(99) // 99
 - 위의 ask 코드를 보면 직전 mapping 결과를 받지만 따로 리턴하지 않습니다. 
 오직 env만 리턴 합니다
map h : v(99) => v + 3
 



このようにaskと読み、マッピングしたものを何セットか作り、chainで合成すると進行中でいつでもaskが読めます.
これはどこに使いますか…考えなければなりません.