純粋に関数型言語で、副作用を導入せずにAPIに接続する方法を知りたいだけです。
2 に答える
Haskell などの純粋関数型言語は、「外部関数インターフェイス」を介して外国語で関数を呼び出すことをサポートしています。
発生する問題は、外国語関数の型と動作を純粋関数型言語 (Haskell など) にエンコードする方法です。
考慮すべき 2 つのケースがあります。
純粋関数
副作用のない外国語の関数は、セマンティックの問題なしに直接埋め込むことができます。例はsin :: CDouble -> CDouble
Cにあります。
不純関数
不純な関数には副作用があります。多くの場合、外国語側で状態を変更します。このような関数は、副作用を正しく順序付けるために、依存関係/順次の順序で呼び出す必要があります。
これを純粋な関数型言語に埋め込むには、状態を表すトークンを外部関数との間で渡します。外部関数を呼び出すたびに、新しいトークンが返され、古いトークンは破棄されます。そう
let state0 = initState
(v, state1) <- foreignFunction state0
(u, state2) <- foreignFunction state1
return (v,u)
副作用は、state
変数を (関連付けによって) 変更する純粋な関数としてキャプチャされます。これらを行き来させることで安全が確保されます。
状態トークンを渡す配管を隠すには、モナドを使用できます。
このアプローチは、たとえば、Haskell のステートフルな外部 API とのインターフェイスでは非常に一般的です。商品例:メルセンヌツイスター製本。MTGen
、ライブラリが初期化されたことの証拠としてトークンを使用します。
API も純粋に機能しない場合は、できません。最善の方法は、コード内で変更効果を簡単に認識できるように、変更効果を分離することです。