2016-10-21 2 views
4

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

let rec addTupLst (xs: 'a * 'a list) = 
    match xs with 
    | (a, b) :: rst -> a + b + (addTupLst rst) 
    | _ -> 0 

addTupLst [(1, 2)] 

Я получаю предупреждение

ошибка FS0001 : Это выражение, как ожидается, иметь тип
«а *» список
, но здесь имеет тип
«список б

Невозможно совпадение с шаблоном в списке кортежей таким образом, или есть еще одна ошибка?

+2

Поместите парсеры вокруг кортежа (xs: ('a *' a)) – Petr

+0

Стоит отметить, что вы также можете просто не включать аннотацию типа, и в этом случае компилятор выберет ее правильно. – TheQuickBrownFox

+0

@ TheQuickBrownFox Хорошая точка. Я часто нахожу, что получаю больше запросов с помощью аннотаций, но в этом случае явно укусил, пытаясь перехитрить компилятор – beardc

ответ

4

Вы просто забыли пару скобок

let rec addTupLst (xs: ('a * 'a) list) = 
    match xs with 
    | (a, b) :: rst -> a + b + (addTupLst rst) 
    | _ -> 0 

addTupLst [(1, 2)] 
2

Проблема заключается в том, что вы объявляете функцию как взятие 'a * 'a list, но то, что вы на самом деле хотите, чтобы написать это ('a * 'a) list.

Это одна из причин, почему мне не очень нравится обычный, но (ИМО) непоследовательный стиль использования префиксной нотации для параметров типа для некоторых встроенных типов и постфиксной нотации для остальных. Я предпочитаю писать тип как list<'a * 'a>.

Смежные вопросы