Принимая сумму списка в Haskell - PullRequest
0 голосов
/ 13 ноября 2018

Я пытаюсь взять сумму списка в Haskell, но выдает ошибку, см. Код ниже.

binListToDec :: [Int] -> Int
binListToDec (x:xs) = if length binListToDec == 0 then 1
                      else x + binListToDec xs

выдает следующую ошибку

 * No instance for (Foldable ((->) [Int]))
        arising from a use of `length'
    * In the first argument of `(==)', namely `length binListToDec'
      In the expression: length binListToDec == 0
      In the expression:
        if length binListToDec == 0 then 1 else x + binListToDec xs
  |
2 | binListToDec (x:xs) = if length binListToDec == 0 then 1

1 Ответ

0 голосов
/ 13 ноября 2018

Среди множества способов написать это можно двумя вариантами:

binListToDec xs = if length xs == 0 then 0  -- see below
                  else (head xs) + binListToDec (tail xs)

и

binListToDec [] = 0
binListToDec (x:xs) = x + binListToDec xs

Похоже, вы пытаетесь объединить биты каждого из них.Невозможно написать один шаблон, который соответствует одновременно 1) пустому списку и 2) непустому списку с 3) его голова и хвост сопоставляются отдельно.

  • xs соответствует 1) и2).
  • all@(x:xs) соответствует 2) и 3)
  • 1) и 3) не может быть сопоставлено , поскольку спаривание бессмысленно: пустоеСписок не имеет отдельной головы и хвоста.[] и (x:xs) совпадают списки из двух неперекрывающихся наборов возможных значений списка.

    Обновление: существует ленивый образец совпадения all@(~(x:xs)).Тильда предотвращает попытку совпадения (x:xs) до тех пор, пока не возникнет необходимость оценить x или xs.Мы думаем о

    binListToDec all@(~(x:xs)) = if length all == 0 then 0 else x + binListToDec
    

    как эквивалентном

    binListToDec all = if length all == 0 
                       then 0
                       else let (x:xs) = all 
                            in x + binListToDec
    

    Ленивое сопоставление с образцом все еще может потерпеть неудачу, но здесь мы откладываем использование x и xs, пока не узнаем, что оно победило 't.


length binListToDec пытается вычислить длину самой функции, а не длину ее аргумента, в вашей попытке.Правильный аргумент для length используется выше.Кроме того, общепринятая сумма пустого списка равна 0, а не 1.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...