私は3つのモナディック関数を用意しています。それらは一緒に構成し、条件付きで述語に分岐したいと考えています。私は多分一般のトレードオフを持つソリューションを探しています。矢印(ArrowChoice?)とMonadsは有望視されています。これらの3種類の関数を条件分岐のために構成する一般的な方法は何ですか?
不自然な問題はこれです:私は、多くのお客様の 『個人番号』を追跡してサービスを実行
。最初にログインした場合、その番号は0に設定されています。以前ログインしていて、おそらく番号が変更されている場合は、その番号がフェッチされます。
したがって、このプログラムの汎用タイプはprogram :: Name -> Int
です。私は他人のために、これらの機能を入れ替えることができるようにしたい
new? :: Name -> Bool
fetch :: Name -> Int
generate :: Name -> Int
:
は、私はすべてのデータの永続ストアに問い合わせるモナド影響を与える可能性があります3つの機能、(例えばDB、国家を)持っています。たとえば、fetchFromDB
、またはfetchFromStateMonad
の場合はfetch
をスワップアウトします。それらを「構成」の
一つの解決策は、次のようになります。
ex1 :: (a -> Bool) -> (a -> b) -> (a -> b) -> (a -> b)
-- or --
ex1 :: (Name -> Bool) -> (Name -> Int) -> (Name -> Int) -> (Name -> Int)
-- predicate fetch generate result
これは、一般的な解決策に私が近づくifM
のようなビットを探します。
しかし、ex1 "John"
を呼び出すと、述語を決定するために1つのデータベース呼び出しが行われ、もう1つはfetch
ジョンの番号になります。 (もちろん、これはこの狭いケースでは簡単に解決できます。より一般的なものを探しています)。
ex2 :: Name -> (Name -> Bool) -> (Name -> Int) -> (Name -> Int) -> Int
-- name predicate fetch generate result
それは、predicate
とfetch
介して1つのデータベースクエリの結果をスレッド化する方法をまだ私には明らかではないが、少なくともこのタイプの署名は、それを可能にすることができます。今は型のシグネチャの問題がありますが、それは合成のようなものではありませんし、さらには特別なものです。
この問題を一般化する方法はありますか?いくつかのcomposition
関数は、任意の述語や関数を意図した方法で結びつけるために必要なすべてを行います。
なぜdownvotes? –