Недопустимая подпись типа Haskell

Быстрый вопрос, что не так с этим?

(get) :: [a] -> Int -> a   -- <- line 21
(x:xs) get 0 = x
(x:xs) get (n+1) = xs get n

ghci выдает эту ошибку, когда я пытаюсь загрузить файл, содержащий этот код.

Prelude> :load ch6.hs 
[1 of 1] Compiling Main             ( ch6.hs, interpreted )

ch6.hs:21:0: Invalid type signature
Failed, modules loaded: none.

Я пытаюсь получить инфиксный оператор.


person Kevin    schedule 30.12.2011    source источник


Ответы (2)


Для начала у вас не должно быть скобок вокруг get. Однако синтаксис всего определения выглядит немного не так. Я предполагаю, что вы хотели что-то вроде этого:

get :: [a] -> Int -> a
get (x:xs) 0 = x
get (x:xs) (n+1) = xs `get` n

Обратите внимание на обратные кавычки вокруг get, чтобы использовать его как инфикс, что необходимо здесь, потому что правила для буквенно-цифрового идентификатора отличаются от операторов: операторы состоят из символов, являются инфиксными по умолчанию, и писать их без аргументов или использовать их префикс , вы заключаете их в скобки. Буквенно-цифровые идентификаторы являются префиксами по умолчанию, и окружение их обратными кавычками позволяет использовать их как инфикс.

Вы также можете использовать обратные кавычки с левой стороны, если хотите, но это выглядит немного странно, на мой взгляд:

(x:xs) `get` 0 = x
(x:xs) `get` (n+1) = xs `get` n

Между прочим, синтаксис шаблона n+1 устарел, поэтому вам, вероятно, не следует его использовать. Вместо этого сделайте следующее:

(x:xs) `get` n = xs `get` (n - 1)
person C. A. McCann    schedule 30.12.2011
comment
Я работаю над prelude. Проверьте источник &&. - person Kevin; 30.12.2011
comment
@Kevin: Вот как это работает для операторов, то есть идентификаторов, состоящих из символов. Синтаксис отличается для буквенно-цифровых идентификаторов. - person C. A. McCann; 30.12.2011
comment
Мало того, что он устарел: он больше не работает в стандартном GHC (и не в Haskell 2010). - person ehird; 30.12.2011
comment
(n+1) работает для меня в любом ghci, входящем в пакет Ubuntu :) - person Kevin; 30.12.2011
comment
@ehird: Это больше не работает, это просто точка, в которой метастазирует агрессивное устаревание. :] - person C. A. McCann; 30.12.2011
comment
@Kevin: О, да, кажется, он все еще включен по умолчанию в последней версии GHC (7.2.2). Должно быть, я неправильно запомнил. Однако они определенно не соответствуют последнему стандарту. - person ehird; 30.12.2011
comment
@ehird Нет, начиная с ghc-7.0.*, NPlusKPatterns по умолчанию отключен. Последним, который не выдает ошибку синтаксического анализа без расширения, является 6.12.3. Где вы взяли 7.*, который принимает их по умолчанию? - person Daniel Fischer; 30.12.2011
comment
@DanielFischer: я использовал документы. - person ehird; 30.12.2011
comment
@ehird: документы, по-видимому, не обновлялись. Спасибо за предупреждение. - person Daniel Fischer; 30.12.2011
comment
@ehird Уже обновлено в HEAD, кажется, забыли внести изменения в ветку 7.2. - person Daniel Fischer; 30.12.2011

То, что вы поместили его в круглые скобки, не делает его инфиксной функцией. Инфиксные функции могут быть выполнены только с помощью символов или обратных кавычек. Подробнее см. в отчете Haskell.

person Thomas M. DuBuisson    schedule 30.12.2011