Разделить строки на списки с помощью Haskell - PullRequest
3 голосов
/ 12 января 2012

Back Story : я боролся с этой проблемой уже на прошлой неделе, читая Learn You A Haskell и учебные пособия онлайн, но я не могу понять этоout.

Я достиг большого прогресса в понимании понимания и рекурсии списков, но эта проблема - единственная вещь, которая все еще стоит у меня на пути.

Вопрос Я пытаюсь преобразовать строку (или, как мне кажется, строку) в разделенный список.Вот код, который у меня есть (спасибо еще раз Ян за помощь).Он импортирует содержимое файла .txt.

import System.Environment

main :: IO ()
main = do
     args <- getArgs
     if null args
       then putStrLn "usage: ./pattern dataset.txt"
       else do contents <- readFile $ head args
               putStrLn $ "Filer1: " ++ filterLower(contents)
               convert' contents

filterLower :: String -> String
filterLower st = [ c | c <- st, c `elem` ['A'..'Z']]

Я попытался создать собственную функцию преобразования:

convert' :: String -> [String]
convert' x = (x:[])

Это работает, но не работает для этой проблемы.

Буду признателен за любую помощь.

Ошибка : это ошибка, которую я регулярно получаю.

Couldn't match expected type `IO ()' with actual type `[String]'
    In the return type of a call of `convert''
    In the expression: convert' contents
    In the expression:
      do { contents <- readFile $ head args;
             putStrLn $ "-: " ++ filterLower contents;
           convert' contents }

Ответы [ 3 ]

6 голосов
/ 12 января 2012

Проблема в том, что результатом convert' является список строк, но вы пытаетесь использовать его как действие ввода-вывода. Вы должны сделать что-то с результатом. Например,

print $ convert' contents

выведет результат на экран. Или вы можете использовать, например, mapM_ putStrLn чтобы распечатать каждый элемент в отдельной строке. Или вы можете дать ему имя и продолжить писать заявления, например:

let converted = convert' contents
...

Судя по вашему комментарию, кажется, что вы пытаетесь разделить строку, чтобы превратить ее в список ее слов, например, convert' "Hello world"["Hello", "world"]. В этом случае вам вообще не нужен convert' - стандартная функция words делает именно это! Таким образом, вы можете просто использовать words contents и вообще не определять convert'.

5 голосов
/ 12 января 2012

convert' :: String -> [String], поэтому convert' contents :: [String] - это просто список строк. Но вы поместили его в блок ввода-вывода,

do contents <- readFile whatever
   putStrLn $ ...
   convert' contents

, где могут появляться только выражения типа IO something. Есть простой способ превратить выражение без ввода-вывода в вещь ввода-вывода, просто return it:

do contents <- readFile ...
   putStrLn $ ...
   return $ convert' contents

правильно напечатано. Но этот do-блок имеет тип IO [String], поэтому он не соответствует объявленному типу main. Как это исправить, зависит от того, что вы хотите, чтобы ваша программа делала.

1 голос
/ 12 января 2012

Я не понимаю, что вы пытаетесь сделать здесь, но самая большая проблема в том, что вы неправильно используете do -блок. main имеет тип IO (), что подразумевает два ограничения:

  • Каждый «пустой» оператор (оператор без <-) в блоке do должен иметь тип IO a для некоторых a.
  • Последний оператор в do -блоке должен иметь тип IO (); Ваш последний оператор имеет тип [String] (и, следовательно, полученную ошибку). Самый простой оператор с этим типом будет return ().
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...