Почему композиция функтора в пустом списке возвращает ошибку Show? - PullRequest
1 голос
/ 13 октября 2019

При вызове следующего, GHCI возвращает ошибку: переменные неоднозначного типа 'f0', 'b0', возникающие из-за использования 'print', предотвращают решение ограничения (Show (f0 b0)) '.

Насколько я понимаю, это потому, что тип моего выражения (Num b, Functor f) => [fb], где f - неоднозначный тип.

Однако экземпляр Functor в List определяетfmap как map, а определение map игнорирует аргумент функции в случае, если вторым аргументом является [], который просто возвращает []. Это должно означать, что мое выражение должно просто возвращать [] независимо от того, сколько композиций fmap я применяю, и вызов show [] должен пройти. Почему я вижу ошибку тогда?

(fmap.fmap) (+1) []

1 Ответ

5 голосов
/ 13 октября 2019

Это правда, что ваша функция всегда будет возвращать [], но диспетчеризация класса типов (которая происходит во время компиляции, а не во время выполнения) должна основываться на типе аргумента show. Экземпляр Show для [a] требует, чтобы Show a также был разрешен (instance Show a => Show [a]) --- поскольку существует много значений типа [a], которые содержат элементы --- и поскольку тип элементов списка (все 0 из них) неоднозначны, ограничение Show не может быть разрешено.

Это может привести к тому, что вы спросите, почему, например, show [] не имеет такой же проблемы, поскольку [] :: [a]. Ответ здесь заключается в том, что GHCi имеет некоторые специальные Расширенные правила по умолчанию эвристики, которые применяются в некоторых простых случаях, чтобы сделать работу в приглашении более приятной. Если вы :set -XNoExtendedDefaultRules, вы можете видеть, что show [] будет вести себя так же. В вашем случае, поскольку тип элемента списка f0 b0, а не переменная одного типа, связанные расширенные правила по умолчанию не применяются, и поэтому тип элемента списка по-прежнему содержит неопределенные переменные типа.

YouМожно увидеть, что это проблема, самостоятельно решив некоторые ограничения типа, скажем, с помощью -XTypeApplications. Даже разрешения ограничения Functor достаточно для повторного применения нормальных правил по умолчанию для типа Haskell: (fmap.(fmap @[])) (+1) [] действительно выводит [] в приглашении GHCi.

...