Почему синонимы типов не разрешают рекурсию в Haskell?

Может ли кто-нибудь объяснить, почему эти оба компилируются успешно:

data A a b = A { a :: a, b :: b }
newtype B a = B (A a (B a))
newtype C = C (A Int C)

Но я не могу создать аналогично рекурсивно определенные типы через синонимы типов?

type B a = A a (B a)
type C = A Int C

Хотя очевидно, что data B a = A { a :: a, b :: B a } работает просто отлично.

Есть ли способ избежать работы с этим дополнительным конструктором X везде, где мне нужен рекурсивный тип? Я в основном передаю функции доступа, которые выбирают b в любом случае, так что я в основном в порядке, но если существует простой механизм обхода, я хотел бы знать о нем.

Какие-нибудь прагмы, которые я должен использовать для улучшения производительности со специализированным типом данных C? Просто специализировать вещи?

Какой-нибудь хитрый трюк для копирования между A a b и A c d, определяющий только отображение a -> b и c -> d без двойного копирования записи? Боюсь, что поля A в будущем изменятся. Может быть, шаблонный Haskell?

20
задан Jeff Burdges 22 January 2012 в 18:16
поделиться