7

Haskell が天気を追跡している関数が関数合成であるかどうか疑問に思っていました。つまり、これと同様のことを行う関数を定義することは可能でしょうか?:

compositionSplit f.g = (f,g)
4

2 に答える 2

18

いいえ、それは不可能です。

例えば、

f1 = (+ 1) . (+ 1) :: Int -> Int

と同じ機能です

f2 = subtract 1 . (+ 3) :: Int -> Int

参照透過性は、equals を equals に置き換えることができることを要求するため、compositionSplit可能であれば、

  • f1とに対して同じ結果を生成する必要がありますf2。これは同じ関数であるためです。
  • compositionSplit f1 = ((+ 1), (+1))compositionSplit f2 = (subtract 1, (+ 3))の仕様で必要とされますcompositionSplit
于 2013-05-29T23:34:42.623 に答える
4

できました。厳密に解釈的な非コンパイル実装では、関数を次のように表すことができます。

data Function = F Source | Compo Function Function

そして、あなたは定義するだけです

compositionSplit (Compo f g) = Just (f,g)
compositionSplit _  = Nothing

そのような実装は、関数の等価性 (参照透過性に関して) を外延的な等価性ではなく、 intensionalとして扱います。言語自体は関数の等価性について何も言っていないので、これは何にも影響しないはずです(おそらくパフォーマンスを除く)。

コンパイル済みの実装では、メモリ内のすべてのオブジェクトの来歴を維持するなど、これも実現できます。


AndrewC は、勝者の反論を示しています。2 つの値a=f.(g.h)b=(f.g).hについて、それらを等しい値と見なしたい場合 (Haskell では通常そうします)、 fst.unJust.deCompo2 つの異なる結果が生成され、参照の透過性が失われます。したがって、純粋な FP パラダイムの一部になることはできません。どちらの場合も、正当に等しい値であると見なすことができる何かを返す必要があり、純粋さを壊さずにそれを分解することはできません。たぶん、そのようなものは不純なモナドに存在する可能性がありますが、残念ながらそれはOPが求めたものではありません。:) したがって、この答えは誤りです。

于 2013-05-30T08:42:16.613 に答える