Ответ 1
Это невозможно, как написано. Типичные синонимы должны быть полностью применены для их использования, особенно как параметр класса типа.
Обратите внимание, что если вы можете eta-уменьшить синоним типа, возможно, экземпляр возможен; это синоним, который должен быть полностью применен, а не тот тип, к которому он относится. Таким образом, это сработает:
type F = (->)
instance C F a b where
doc f x = f x
Существует расширение LiberalTypeSynonyms
, которое смягчает некоторые правила о расширении синонимов типов, но здесь это не помогает - это только позволяет делать такие вещи, как дать частично примененный синоним типа как параметр типа синонима другого типа. Все должно быть полностью расширено для использования в противном случае.
Чтобы увидеть, почему это ограничение необходимо, рассмотрите синоним следующего типа:
type Flip f a b = f b a
И следующий пример:
instance Functor (Flip Either a) where
fmap _ (Right x) = Right x
fmap f (Left x) = Left (f x)
Вспомните, что есть также экземпляр Functor (Either a)
, который делает то же самое, кроме зеркального отображения. Оба являются разумными экземплярами Functor
.
Помня о том, что в отличие от newtype
, синонимы типов считаются такими же, как тип, на который они ссылаются, каково должно быть значение выражения fmap not (Right True :: Either Bool Bool)
?