Вопрос 1
Вы ошиблись.Flip
означает, что вам необходимо сопоставить параметр first K
:
instance Functor (Flip K a) where
fmap f (Flip (K a)) = Flip (K (f a))
Вопрос 2
Для этого есть веские причины.Одним из них является то, что может быть чрезвычайно полезно (для поддержки программных инвариантов или для управления разрешением экземпляра) задавать параметр типа phantom .Эти методы были бы бесполезны, если бы компилятор их просто игнорировал.(Примечание: вы можете игнорировать их, когда вам это нужно, и Data.Coerce
предоставляет некоторые продвинутые инструменты для этого. Вы, вероятно, еще не готовы к принуждению).
Другая причина в том, что это будет значительно сложнеечтобы выяснить, какие типы были равны другим типам, так как вам нужно будет рассмотреть детали каждого из них.Вероятно, есть и другие причины.
Отклонение
FlexibleInstances
кажется здесь довольно неловким и ограничивающим.Вот как я это сделаю:
-- A functor in the second to last type argument
class Functor2 p where
fmap2 :: (a -> a') -> p a b -> p a' b
instance Functor2 K where
fmap2 = -- you fill in the blank
instance Functor2 p => Functor (Flip p b) where
fmap = -- you fill in the blank