21

Functorandのような抽象化を使用することでコードが恩恵を受ける状況に遭遇しましたApplicativeが、種類は(* -> *) -> *. 高カインド ファンクターの定義は、次のRankNTypesように行うことができます

class HFunctor f where
    hfmap :: (forall x. a x -> b x) -> f a -> f b

しかし、より高い種類の のバージョンはApplicative少しトリッキーです。これは私が思いつくことができる最高のものです:

class HFunctor f => HApplicative f where
    hpure  :: (forall x. a x) -> f a
    (<**>) :: f (a :-> b) -> f a -> f b

newtype (:->) a b x = HFunc (a x -> b x)

infixr 5 :->

:->kind の関数を持つにはラッパー型が必要ですが、これでは、通常の Applicative の場合の* -> *ように、関数アプリケーションを適切に連鎖させることはできません。などのヘルパーで管理できます<$><*>

liftHA2 :: HApplicative f => (forall x. a x -> b x -> c x) -> f a -> f b -> f c
liftHA2 f fa fb = hpure (fun2 f) <**> fa <**> fb where
    fun2 = HFunc . (HFunc .)

しかし、任意のアリティの関数を「持ち上げる」ための一般的な方法があると便利です。

上記のインスタンスを使用する簡単な例:

data Example f = Example (f Int) (f String)

instance HFunctor Example where
    hfmap f (Example i s) = Example (f i) (f s)

instance HApplicative Example where
    hpure a = Example a a
    Example (HFunc fi) (HFunc fs) <**> Example i s = Example (fi i) (fs s)

e :: Example []
e = Example [1,2,3] ["foo", "bar"]

e' :: Example ((,) Int)
e' = hfmap (length &&& head) e  -- Example (3,1) (2, "foo")

e'' :: Example []
e'' = liftHA2 (++) e e  -- Example [1,2,3,1,2,3] ["foo", "bar", "foo", "bar"]

だから、私の質問は:上記の型クラスは何と呼ばれ、それらはハックのいくつかのライブラリによってすでに提供されていますか? Functor2グーグルで私はinlinear-mapsHFunctorinを思いつきましたmulti-recが、どちらも私が必要としているものを正確にはしません。

HApplicativeまた、ラッパーなしで書く方法:->や、関数のリフティングを容易にする他の方法はありますか?

4

1 に答える 1

2

私が考えがちな HFunctor は、(* -> *) -> * -> *つまり、ファンクター上の正当なファンクターです。これはあなたが考えているものとは異なる特徴を持っています。

それを定義する方法と、それに対するアプリケーションの「モノイド」バージョンを次に示します。

type Nat f g = forall a. f a -> g a

class HFunctor (f :: (* -> *) -> * -> *) where
    hfmap :: (Nat g h) -> Nat (f g) (f h)

data Prod f g a = Prod (f a) (g a)

class HFunctor f => HApplicative f where
    hpure  :: Nat g (f g)
    htensor :: Nat (Prod (f g) (f h)) (f (Prod g h))

これが何であるか、そしてそれをどのように使用するかについてのいくつかのアイデアで、後で更新しようとします。

これはまさにあなたが求めているものではないことは承知していますが、あなたの投稿に触発されて試してみました.

あなたの特定のユースケースにも興味があります。

あなたの 2 つの具体的な質問に対して A) あなたが説明する HFunctor は、以前にさまざまな機会に説明されています。特に Gibbons によって説明されていますが、パッケージ化されていることは知りません。確かに Applicative は見たことがありません。B) 型シノニムを部分的に適用できないため、ラッパーに行き詰まっていると思います。

于 2013-08-07T01:42:39.247 に答える