Как я могу использовать синоним типа в объявлении экземпляра?

#haskell

#haskell

Вопрос:

Я хотел бы создать синонимы для ограничения класса, как в следующем (очень упрощенном) примере

 {-# LANGUAGE ConstraintKinds #-}

type Foo = Functor

data MyFunctor a = MyFunctor

instance Foo MyFunctor where
  fmap _ _ = MyFunctor
 

но я получаю fmap is not a (visible) method of class Foo .

Похоже, я должен быть в состоянии сделать это, потому что в документации GHC говорится: «… стандартные ограничения, кортежи и синонимы типов для этих двух видов ограничений разрешены в контекстах экземпляров и суперклассах». Я на GHC 7.6.

Комментарии:

1. Я столкнулся с этой проблемой и нашел этот вопрос, только чтобы обнаружить, что исходный вопрос был написан мной четыре года назад. Я могу подтвердить, что это поведение все еще раздражает.

Ответ №1:

Ваш случай не охвачен этими утверждениями в документации GHC. Использование контекста экземпляра Foo — это что-то вроде:

  instance Foo a => Bar a
 

Суперкласс будет выглядеть примерно так:

  class Foo a => Bar a
 

т.е. Вы определяете какой-то другой класс или экземпляр и Foo / Functor является одним из требований. Здесь вы на самом деле пытаетесь определить Functor себя, и вам нужно использовать реальное имя класса.

Комментарии:

1. Я понимаю. Что может пойти не так при использовании синонимов типов вместо реального имени класса? Приведет ли это к циклу, подобному примеру в документе GHC? (Я должен сказать, что я все равно этого не понимаю …)

2. На мой взгляд, просто путаница пользователей и усложнение языка. Также, например, что будет делать объявление экземпляра для типа Foo a = (Eq a, Ord a) ? Конечно, можно представить, как это может работать, но это не совсем тривиально.

3. Ну, я полагаю, что синоним типа должен быть разрешен для чего-то, для чего вы можете предоставить экземпляр. В любом случае, я хотел использовать его для уменьшения шаблонности, потому что у меня есть MPTC, ClassName profunctorType a b и я хочу, чтобы мои пользователи предоставляли экземпляры, подобные ClassName MyProfunctor (MyWrapper TheirType) TheirType , и я бы очень хотел type Foo theirType = ClassName MyProfunctor (MyWrapper theirType) TheirType , чтобы они могли вместо этого предоставлять экземпляры for Foo TheirType .