Подпись недопустимого типа на Haskell - PullRequest
4 голосов
/ 30 декабря 2011

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

(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.

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

Ответы [ 2 ]

12 голосов
/ 30 декабря 2011

У вас не должно быть скобок около 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)
2 голосов
/ 30 декабря 2011

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

...