Haskell, даже если мой тип не указан, я получаю эту ошибку: не удалось сопоставить тип `a 'с` [a]', `a '- это переменная жесткого типа, связанная с - PullRequest
5 голосов
/ 13 ноября 2011

Итак, я понимаю, что это возможный дублирующий вопрос, так как о переполнении стека сообщалось о ряде этих ошибок, но ни одно из решений, похоже, не относится к моей проблеме.

Итак, у меня есть следующая функция:

elementAt' :: Integral b => [a] -> b -> a
elementAt' [x:_] 1 = x
elementAt' [x:xs] y = elementAt' xs yminus1
    where yminus1 = y - 1

Если вам интересно, это проблема 3 из 99 Задачи Хаскелла .Цель функции - взять в качестве входных данных список и индекс и вернуть значение по этому индексу (начиная с 1).Я не хочу, чтобы решение проблемы, если бы я сделал, я мог бы просто посмотреть на предоставленные.Но я получаю ошибку, которую не понимаю.Я использую eclipseFP, плагин eclipse для haskell, и он подчеркивает части «[x: _]» и «[x: xs]» со следующей ошибкой:

Couldn't match type `a' with `[a]'
`a' is a rigid type variable bound by
the type signature for elementAt' :: Integral b => [a] -> b -> a

Во всехпотоки, обсуждающие эту ошибку, на которую я смотрел, обычно возникают, когда кто-то пытается дать неправильный вывод чему-то, что ожидает определенный тип.Например, возвращая длину чего-либо (который имеет тип Int) тому, что должно быть типом переменной «Num a».

Но в моем случае я даже не предоставляю тип для переменной a.Это должно быть в состоянии быть НИЧЕГО, верно?Так почему я получаю эту ошибку?Если бы я понял, почему я получаю ошибку, я мог бы ее исправить, но я просто не понимаю.

Может кто-нибудь объяснить мне, почему я получаю эту ошибку?

Ваша помощьвысоко ценится, спасибо.-Asaf

Редактировать: Каждый ответ, предоставленный до сих пор, является правильным, спасибо всем за полезную информацию.Я собираюсь выбрать тот, который мне кажется наиболее понятным (хотя мне нужно подождать 5 минут, чтобы сделать это).

Ответы [ 4 ]

9 голосов
/ 13 ноября 2011

Ввод вашего определения без объявления типа показывает, что выведенный тип - Integral b => [[a]] -> b -> a.Это верно, ваши текущие шаблоны соответствуют спискам списков.

Шаблону типа

f [pat] = ...

соответствует одноэлементный список, единственный элемент которого соответствует pat.Вы хотите работать с cons aka (:) вместо запроса определенной длины, а затем вам нужно заключить в скобки вместо скобок:

elementAt' (x:xs) n = ...

Ошибка в основном говорит "вы обрабатываете a (элементыпервого аргумента), как если бы это был список ".

3 голосов
/ 13 ноября 2011

Но в моем случае я даже не предоставляю тип для переменной a.Оно должно быть НИЧЕГО, верно?

Оно должно быть в состоянии быть чем угодно.В соответствии с вашей сигнатурой типа пользователь вашей функции должен иметь возможность вызывать вашу функцию с a, равным Int, с a, равным [Char] или с `a ', являющимся тем, что пользователь хочет.

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

3 голосов
/ 13 ноября 2011

Если вы хотите сопоставить список с головой и хвостом, вы должны использовать

elementAt' (x:_) 1 = x

Итак, наконец

elementAt' :: Integral b => [a] -> b -> a
elementAt' (x:_) 1 = x
elementAt' (x:xs) y = elementAt' xs yminus1
    where yminus1 = y - 1

И

λ> elementAt' [1,2,3] 2
2

Эточто тебе нужно?

1 голос
/ 13 ноября 2011

Используйте скобки, а не скобки: (x:xs)

module Aaa where

elementAt' (x:_) 1 = x
elementAt' (x:xs) y = elementAt' xs yminus1
    where yminus1 = y - 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...