T - タグ付け
分かりやすくするために、タイプの名前を変更したいと思います。T
値に数値を割り当てます。コンテナーの構造が不明なため (そして柔軟性を維持したいので)、値と数値をペアでポップします(x,n)
。そのタグ付けを reaname と呼びましょう。あなたのコレクションタイプがs のコレクションであるT
Tagger
ことがわかっていると仮定すると、 typeが必要になるので、必要になりますColl
X
Coll X
type CollTaggerXInt = Coll X -> Coll (X,Int)
これにより、必要な関数の型シノニムが作成されます。
しかし、が小さすぎてやその他の数値型Int
を使用したい場合はどうでしょうか。Integer
Double
data Num n => CollTaggerX n = CollTaggerX (Coll X -> Coll (X,n))
X
これは、任意の固定タイプの数値データで値にタグを付けることができることを意味します。(Num n =>
は、n が数値型でなければならないことを表明するデータ型制約です。) 右側の CollTaggerX は、タグ付け関数を軽量コンストラクターでラップすることにより、型の安全性を保証します。でパラメータ化したので、data
代わりにを使用する必要があります。type
n
コードの再利用を改善するために、固定型X
とコレクション型を型パラメーター (Java などの一部の言語のジェネリックなど)に置き換える傾向があります。Coll
data (Functor coll,Num n) => Tagger coll x n = Tgr (coll x -> coll (x,n))
coll
そのため、 ection タイプは Functor であると主張したので、fmap
関数をポイントごとにコレクションに適用するために使用できます (あなたのケースでは重要であり、どのコレクション タイプも Functor のインスタンスになります)。
私はTagger
for yourのその定義に最も満足していますが、 , andの可能性が 1 つしかない場合にT
使用できます。CollTaggerXInt
coll
x
n
U - タガーの作成
あなたのU
タイプは、要素ごとのタガーをコレクションのタガーに変えるためのものです。Lift
ではなく、ingと呼んでいるような気がしU
ます。を使用している場合はCollTaggerXInt
、型シノニムを再度使用できます。
type LiftXIntToTagger = (X -> Int) -> Coll X -> Coll (X,Int)
または、より柔軟なTagger
定義を使用している場合は、次のように書くことができます
data (Functor coll,Num n) => Lifter coll x n = Lifter ((x -> n) -> coll x -> coll (x,n))
しかし、これはすべて、これの型を作成するのは気が狂っているように感じます。なぜなら、ポイントごとの関数がある場合は、とにかく型fmap
で機能する which を使用して、すでにそれを持ち上げることができるからです。coll
fmap :: Functor f => (a -> b) -> f a -> f b
したがって、これをcoll
as f
、x
as a
、(x,n)
as b で使用して、定義することができます
liftT :: (Functor coll,Num n) => (x -> n) -> coll x -> coll (x,n)
liftT f = fmap tag where
tag x = (x,f x)
あなたのタイプを定義したいのなら、OKですが、あなたのタイプでliftT
唯一の賢明な関数かもしれないと思いますU
。
ランク - U+コンテキスト
あなたのランクの例は役に立つと思うので、それを調べてみましょう。ランク関数はコレクションのすべての要素を調べる必要があるため、コレクション全体を最初のパラメーターとしてrankfunction :: coll x -> x -> n
( context 内で(Functor coll,Num n)
) 与えましょう。
liftInContext :: (Functor coll,Num n) => (coll x -> x -> n) -> coll x -> coll (x,n)
liftInContext rankfunction mycoll = liftT (rankfunction mycoll) mycoll
ここで関数(rankfunction mycoll)
は、liftT を使用して各要素に適用する前に、rankfunction にその最初のパラメーター (コレクション全体) を渡します。これは部分評価と呼ばれ、このような場合に非常に便利です。