2015-09-11 2 views
3

Итак, я пытаюсь выполнить triplize элемент, т. Е. Сделать еще 2 копии этого элемента.Почему это определение не охватывает все случаи шаблонов?

Так я написал это:

triplize :: [a] -> [a] 
triplize [x] = concatMap (replicate 3) [x] 

Но я получаю эту ошибку:

Non-exhaustive patterns in function triplize 

Я новичок в Haskell, поэтому любые указатели оценены!

+1

А когда список пуст. Вы не поймаете этот случай? –

+0

Не нужно учитывать это: – user32132321

+1

@NeedHelp Да, вы это делаете. 'triplize [] = []', по вашему определению. Неполные функции считаются вредными. – AJFarmar

ответ

7

Когда вы пишете

triplize [x] 

Вы говорите, что аргумент должен соответствовать шаблону [x]. Этот шаблон представляет список с единственным значением, которое будет присвоено имени x. Обратите внимание, что список не будет присвоен имени x, только единственное значение в этом списке. Если вы попытались позвонить своей функции со списком [] или [1, 2], это приведет к ошибке, потому что вы не сказали своей функции, что делать с этими входами.

То, что вы, вероятно, хотите,

triplize x = concatMap (replicate 3) x 

Здесь ваш шаблон просто x, который соответствует любому списку, из пустого списка бесконечного списка. Обратите внимание, что шаблоны в определении вашей функции соответствуют тому, как вы сами делаете значения. В Haskell вы можете сопоставлять соответствие конструкторам, а списки могут быть построены с квадратными скобками и запятыми или они могут быть построены с использованием оператора :, поэтому [1, 2, 3] == (1:2:3:[]). Фактически, оператор : - это то, как Haskell представляет списки внутри.

Пример, который использует больше соответствия шаблону:

sumSuccessive :: [Int] -> [Int] 
sumSuccessive [] = []  -- Empty list 
sumSuccessive [x] = [x] -- Singleton list (only one value) 
sumSuccessive (x:y:rest) = x + y : sumSuccessive rest 
    -- Match a list with at least two elements `x` and `y`, 
    -- with the rest of the list assigned to the name `rest` 

В этом примере функция будет взять список [1, 2, 3, 4] и вернуть список [3, 7] ([1 + 2, 3 + 4]).

+0

Спасибо, Большая помощь! – user32132321

+0

Общей идиомой для именования таких параметров является использование 'xs' или подобных для имен списков. Например. 'triplize xs = concatMap (replicate 3) xs' – Oly

3

Вы можете определить triplize как:

triplize :: [a] -> [a] 
triplize x = concatMap (replicate 3) x 

Но нет даже нет необходимости писать x:

triplize :: [a] -> [a] 
triplize = concatMap (replicate 3) 

Исходный код будет работать только в списках с одним элементом:

> triplize [1] 
[1, 1, 1] 
> triplize [] 
*** Exception: Non-exhaustive patterns in function triplize 
> triplize [0, 1] 
*** Exception: Non-exhaustive patterns in function triplize 
0

[x] соответствует списку ex actly один элемент. Если вы хотите, чтобы соответствовать любой список, просто удалить [ и ]:

triplize x = concatMap (replicate 3) x 

Это превратит ["a", "b", "c"] в ["a", "a", "a", "b", "b", "b", "c", "c", "c"].

С другой стороны, если вы хотите взять один элемент и возвращает список (содержащий 3 этого элемента), то ваш код должен быть

triplize :: a -> [a] 
triplize x = replicate 3 x 

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

  • Нет связанных вопросов^_^