Вы не можете сопоставить шаблон с функцией с переменной типа снаружи. Чтобы понять почему, давайте посмотрим на ваш код:
data Bar = Bar
data Foo = AA Bar | BB Bar | CC Bar | DD Bar
funky :: x Bar -> Bar
Сигнатура типа для funky
утверждает, что она принимает значение типа x Bar
и возвращает значение типа Bar
. Важно, что он может сделать это для любого типа x
соответствующего типа - вот что означает переменная типа.
Теперь, чтобы увидеть проблему с этим, рассмотрим этот тип:
data Ignore a = Ignored
То есть для любого типа a
существует только одно значение типа Ignore a
, и это значение равно Ignored
.
Поэтому, используя этот тип, если мы возьмите x ~ Ignore
, затем funky
станет funky :: Ignore Bar -> Bar
. Проблема здесь должна быть очевидной: в Ignore Bar
не хранится значение типа Bar
! Так что нет никакого способа сопоставить с шаблоном Ignore Bar
и получить Bar
. И, следовательно, вообще нет способа написать функцию funky :: x Bar -> Bar
, которая делает то, что вы хотите.