Странная ошибка при использовании переменных типа scoped и комбинатора y в haskell - PullRequest
2 голосов
/ 04 мая 2011

Так что я играю с y-комбинатором и анонимными функциями, и я столкнулся с этой странной ошибкой:

Couldn't match expected type `t0 -> t1 -> t2'
            with actual type `forall b. b -> [b] -> [b]'
The lambda expression `\ (n :: Int) newVal xs -> ...'
has three arguments,
but its type `Int -> forall b. b -> [b] -> [b]' has only one

( исходный код, который создает ошибку , и версия, с которой я в итоге начал работать )

Если я слегка изменю типы, чтобы избежать полиморфизма ранга N (используйте forall b. Int -> b -> [b] -> [b]) , ошибка будет аналогичной:

Couldn't match expected type `t0 -> t1 -> t2 -> t3'
            with actual type `forall b. Int -> b -> [b] -> [b]'
The lambda expression `\ (n :: Int) newVal xs -> ...'
has three arguments,
but its type `forall b. Int -> b -> [b] -> [b]' has none

Может ли кто-нибудь объяснить мне, почему у forall b. b -> [b] -> [b] нет аргументов?

Ответы [ 3 ]

2 голосов
/ 04 мая 2011

Поскольку вы используете GHC 7, эта причина, по-видимому, имеет ту же основную причину, что и ошибка, сообщенная в http://hackage.haskell.org/trac/ghc/ticket/4347. Хотя в этом сообщении об ошибке говорится о непредсказуемом полиморфизме, похоже, что это, скорее всего, проблема объединения в полиморфизме более высокого ранга. В вашем случае это вызвано тем, что вы поставили forall, что делает тип синтаксически ранг-2.

Обратите внимание, что это на самом деле не ошибка. Дальнейшее разъяснение проясняет, что это предполагаемое поведение, в котором полиморфные экземпляры типов, включая типы ранга N и типы непредсказуемости, не выводятся. Тщательное добавление типовых подписей может заставить его работать.

Но так как тип не был предназначен для более высокого ранга, в вашем случае лучше всего просто избавиться от этого.

0 голосов
/ 04 мая 2011

Я предположил, что вы записали неправильные типы.

Удаление аннотаций типов несколько помогает, что приводит к менее запутанным ошибкам:

A.hs:7:76:
    Occurs check: cannot construct the infinite type: a0 = [a0]
    In the third argument of `replaceNth', namely `arg'
    In the expression: replaceNth m (replaceNth n v (arg !! m)) arg

, поэтому

 \m n v arg -> replaceNth m (replaceNth n v (arg !! m)) arg

уже имеет проблемы.


Типы ранга N и переменные типа с лексической областью

Используя forall не в крайнем положении,вы наткнулись на ранг N типов .forall на вашем внутреннем b говорит о том, что оно должно быть непрозрачным, полиморфным и не связанным с другими типами использования b.Скорее всего, это не то, что вы намеревались сделать.

Это тонко отличается от переменных типа с лексической областью , которые также могут быть введены путем ввода в крайнюю позицию , как описано здесь .

Удалив (я думаю) ошибочные forall s в не внешней позиции, вы получите гораздо более простые ошибки типа.

0 голосов
/ 04 мая 2011

Вы скорее хотите

forall b. Int -> b -> [b] -> [b]

или действительно

Int -> forall b . b -> [b] -> [b]

Я бы прочитал последнее: функция, которая принимает Int и возвращает ЧТО-ТО НЕОБХОДИМО, ЧТО ТОЛЬКО НЕ ТО, ЧЕМ ВЫ ДУМАЕТЕ, ЧТО ЭТО .

...