Haskell: функция, получающая нулевой список - PullRequest
0 голосов
/ 11 октября 2011

Вот некоторые определения типов в моей программе FYI:

type BitString -> String

type Plateau -> [BitString]

У меня есть функция с именем:

--Extract will take a list of lists, and return the inner list of the most items. Empty list should return ["00000"]


extract::[Plateau]->Plateau
extract _ = ["00000"]
extract (x:xs)
  |x==maximumBy(compare `on` length)xs=x  --thanks SOF
  |otherwise = extract (xs)

Проблема в том, что независимо от того, что я делаю, извлечение возвращает ["00000"]

Вот некоторые выходы из GHCI, которые работают:

>plateau graycodes
[["01000"],["01010","11010","10010"],["00101"],["01101","01001"]]

это ожидается и имеет форму [Plateau], так как это список списков строк.

>maximumBy(compare `on` length)(plateau graycodes)
["01010","11010","10010"]

>extract (plateau graycodes)
["00000"]

в этом случае я точно знаю, что extract будет вызываться с непустым [Plateau]. Но часть функции _ возвращается.

Я пробовал также:

extract (x:xs)
  |x==[]=["00000"]
  |x==[""]=["00000"]
  |x==maximumBy(compare `on` length)xs=x  --thanks SOF
  |otherwise = extract (xs)


error: List.maximumBy: Empty list

Ответы [ 3 ]

4 голосов
/ 11 октября 2011

Когда вы определяете функцию с несколькими шаблонами, они будут пробоваться в порядке сверху вниз. Проблема в том, что ваш самый верхний шаблон extract будет соответствовать чему угодно , и поэтому всегда будет выбран первый случай.

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

extract []     = ["00000"]
extract (x:xs) = ...
2 голосов
/ 11 октября 2011

вы получаете эту ошибку, потому что вы не передаете в своем списке (x:xs) максимуму:

extract :: [Plateau] -> Plateau
extract (x:xs)
    |x == maximumBy (compare `on` length) (x:xs) = x
    |otherwise = extract (xs)
extract _ = ["00000"]

или, предпочтительно,

extract :: [Plateau] -> Plateau
extract s@(x:xs)
    |x == maximumBy (compare `on` length) s = x
    |otherwise = extract (xs)
extract _ = ["00000"]

(это также добавляет необходимые = после вашего otherwise)

EDIT:

Меня не удовлетворил мой ответ или ваше согласие с этим ответом.

Я считаю, что это код, который вы действительно после:

extract :: [Plateau] -> Plateau
extract (x:[]) = x
extract s@(x:xs) = maximumBy (compare `on` length) s
extract _ = ["00000"]
0 голосов
/ 11 октября 2011

Решение простое, поменяйте местами шкафы выписки. Шаблон extract _ всегда будет совпадать, таким образом, второй случай никогда не будет выполнен.

Рабочий код (надеюсь):

--Extract will take a list of lists, and return the inner list of the most items. Empty list should return ["00000"]

extract::[Plateau]->Plateau
extract (x:xs)
  |x==maximumBy(compare `on` length)=x  --thanks SOF
  |otherwise extract (xs)
extract _ = ["00000"]
...