Сопоставление с образцом в функции Haskell с переменной типа - PullRequest
0 голосов
/ 18 апреля 2020

В Haskell возможно ли сопоставление с образцом для функций, которые имеют переменную типа для внешнего, но не внутреннего типа? Здесь, например, funky берет любой конструктор типов, который принимает Bar. Хотя это работает для деструктурирования двух случаев, я не уверен, как написать глобальный случай внизу, который в идеале должен возвращать результат деструктурирования. Я поставил вопросительный знак перед q, потому что это то, что озадачивает меня - я не уверен, как деструктурировать это последнее сопоставление с образцом, чтобы получить Bar. Заранее спасибо за помощь!

data Bar = Bar
data Foo = AA Bar | BB Bar | CC Bar | DD Bar

funky :: x Bar -> Bar
funky (AA z) = z
funky (BB z) = z
funky (? q) = q

1 Ответ

3 голосов
/ 18 апреля 2020

Вы не можете сопоставить шаблон с функцией с переменной типа снаружи. Чтобы понять почему, давайте посмотрим на ваш код:

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, которая делает то, что вы хотите.

...