質問

私はこのようなことを書きました:

instance Functor (Either e) where

   fmap _ (Left a) = Left a

   fmap f (Right b) = Right (f b)

必要に応じて同じことをするにはどうすればよいですか fmap 値を変更する場合のみ Left?

つまり、タイプを使用していることを示すためにどの構文を使用していますか Either _ b それ以外の Either a _?

役に立ちましたか?

解決

残念ながら、それを直接行う方法はないと思います。機能を使用すると、使用できます flip 2番目の引数を部分的に適用するが、それは次のような型コンストラクターでは機能しません Either.

最も簡単なことは、おそらくそれをaで包むことです newtype:

newtype Mirror b a = Mirrored (Either a b)

instance Functor (Mirror e) where
    fmap _ (Mirrored (Right a)) = Mirrored $ Right a
    fmap f (Mirrored (Left b)) = Mirrored $ Left (f b)

包みます newtype また、単一のタイプの複数のインスタンスを作成する標準的な方法でもあります。 SumProduct のインスタンスであること Monoid 数値タイプ用。それ以外の場合は、タイプごとに1つのインスタンスしか持てません。

さらに、それが何をしたいのかに応じて、別のオプションは無視することです Functor 次のような独自のタイプクラスを定義します。

class Bifunctor f where
    bimap :: (a -> c) -> (b -> d) -> f a b -> f c d

instance Bifunctor Either where
    bimap f _ (Left a)  = Left  $ f a
    bimap _ g (Right b) = Right $ g b

instance Bifunctor (,) where
    bimap f g (a, b) = (f a, g b)

明らかに、そのクラスはレギュラーの2倍の楽しいです Functor. 。もちろん、あなたは作ることはできません Monad それから非常に簡単にインスタンスします。

他のヒント

探しているインスタンスを直接作成することはできません。

タイプの推論とタイプクラスが機能するためには、タイプの引数の順序付けに特定の位置的バイアスがあります。タイプクラスをインスタンス化するときに引数の任意の並べ替えを許可した場合、そのタイプの推論が扱いやすくなることが示されています。

aを使用できます Bifunctor 両方の引数を個別にマッピングできるクラス。

class Bifunctor f where
    bimap :: (a -> b) -> (c -> d) -> f a c -> f b d
    first :: (a -> b) -> f a c -> f b c
    second :: (c -> d) -> f a c -> f a d

    first f = bimap f id
    second = bimap id

instance Bifunctor Either where
    bimap f _ (Left a) = Left (f a)
    bimap _ g (Right b) = Right (g b)

instance Bifunctor (,) where
    bimap f g (a,b) = (f a, g b)

または、aを使用できます Flip Combinator like:

newtype Flip f a b = Flip { unFlip :: f b a }

これらの両方の一般化されたバージョンは、ハッケージ上のカテゴリエクストラで入手できます。後者には、インスタンスも含まれています Functor (Flip Either a) なぜなら Either aです Bifunctor. 。 (私はおそらくそれを修正する必要があります PFunctor)

最終的に、タイプコンストラクターの引数の順序は、どのクラスをインスタンス化できるかを決定する上で重要です。 NewTypeラッパーを使用する必要がある場合があります( Flip 上記)別のタイプクラスのインスタンスを構築するために資格を得るために必要な議論を置く。これは、型クラスの制約の推論に対して支払う価格です。

本質的にタイプに「フリップ」コンビネーターが必要です。 Camccannが言うように、順序を反転させる新しいラッパーが機能するはずです。 「タイプ」の同義語は、部分的に適用されない可能性があるため、使用できないことに注意してください。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top