Ошибка возникает из-за того, что read x
имеет тип Double
, а не [Double]
, но в его нынешнем виде ваша функция не будет работать должным образом даже с этим исправлением.
Давайте возьмем вашу функцию и поместим ее в слова: «Возьмите передний элемент списка строк, прочитайте его как двойной, а затем сделайте то же самое с остальной частью списка». Теперь давайте посмотрим на вашу функцию:
stringToDouble :: [String] -> [Double]
stringToDouble [] = error "empty list"
stringToDouble [x] = read x :: Double -- Error
stringToDouble (x:xs) = stringToDouble xs
Теперь давайте применим исправление к нему. Кроме того, нет причин для ошибки в пустом списке; просто введите и пустой список парных:
stringToDouble :: [String] -> [Double]
stringToDouble [] = []
stringToDouble [x] = [read x :: Double] -- Put the single value into a list
stringToDouble (x:xs) = stringToDouble xs
Проблема заключается в рекурсивном шаге. Вызов stringToDouble
в списке совпадает с вызовом stringToDouble
в хвосте списка. Первый элемент просто отбрасывается. Вы хотите преобразовать голову и вернуть ее обратно в список.
stringToDouble :: [String] -> [Double]
stringToDouble [] = []
stringToDouble [x] = [read x :: Double] -- Put the single value into a list
stringToDouble (x:xs) = (read x :: Double) : stringToDouble xs
Где (:)
оператор используется для прикрепления элемента к передней части списка. И при этом средняя линия даже не нужна, поскольку рекурсивный шаг будет обрабатывать преобразование, а пустой шаг списка будет обрабатывать условие остановки.
stringToDouble :: [String] -> [Double]
stringToDouble [] = []
stringToDouble (x:xs) = (read x :: Double) : stringToDouble xs
Теперь реально, вы могли бы, вероятно, удалить :: Double
часть и Haskell бы понять, что вы имели в виду с ограничением по типу функции, но это не повредит, и иногда помогает читаемость покинуть его in.
Большое спасибо за объяснение. Что вы предлагаете, если у меня есть список вроде этого? ["A", "1.2"] '..как я могу использовать только числа, а не слова, чтобы игнорировать «а»? Может быть, по регулярному выражению? – letsjak
Что значит «проигнорировано»? Что вы хотите, чтобы не цифры? Вы не можете иметь гетерогенный список в Haskell, так что у вас не может быть, например, ["a", 1.2], поскольку он не имеет допустимого типа. –
Если целью является игнорировать значения, которые невозможно прочитать, тогда определите 'readMaybe x = case читает x of {[(y," ")] -> Just y; _ -> Nothing} 'и' stringToDouble = catMaybes. карта readMaybe' – user2407038