Haskell - Сохранение строкового ввода в список - PullRequest
1 голос
/ 04 августа 2020

Я Haskell новичок, и я делаю небольшой файл для проекта, который должен вводить данные взаимодействия для групп из двух человек и сохранять их в списке для вывода в конце. Я сделал все возможное, чтобы реализовать это, но похоже, что программа попадает в «стоп» независимо от того, что вводится. Любая помощь или совет будут оценены.

import Data.List
import Text.Read

main :: IO ()
main = do
    putStrLn "This program is a means to record interactions between individuals during the COVID-19 pandemic."
    putStrLn "Please enter your interactions in this format: 'x interacted with y'"
    inputs <- getUserInputs
    putStr "input: "
    putStrLn ("list sequence " ++ show (inputs))

parseInput :: String -> Maybe String
parseInput input = if input == "stop" then Nothing else (readMaybe input):: Maybe String

getUserInputs :: IO [String]
getUserInputs = do 
    input <- getLine
    case parseInput input of
    Nothing -> return []
    Just aString -> do
        moreinputs <- getUserInputs
        return (aString : moreinputs)

1 Ответ

0 голосов
/ 04 августа 2020

Show и Read предназначены для создания и использования представления значения как выражения Haskell. Вот почему, когда вы вызываете show на String, он создает строку в кавычках :

> show "beans"
"\"beans\""

Поэтому Read ожидает, что строка также будет заключена в кавычки, поэтому readMaybe всегда возвращает Nothing в вашем коде, потому что вы не предоставляете кавычки:

> readMaybe "beans" :: Maybe String
Nothing

> readMaybe "\"beans\"" :: Maybe String
Just "beans"

Поэтому исправление простое: удалите вызов readMaybe и просто верните строку напрямую:

parseInput1 :: String -> Maybe String
parseInput1 input = if input == "stop"
  then Nothing
  else Just input

Что, в зависимости от предпочтения стиля, вы также можете писать с помощью охранников, сопоставления с образцом или монады Maybe вместо if:

parseInput2 input
  | input == "stop" = Nothing
  | otherwise = Just input
parseInput3 "stop" = Nothing
parseInput3 input = Just input
import Control.Monad (guard)

parseInput4 input = do
  -- ‘guard’ returns ‘Nothing’,
  -- short-circuiting the ‘do’ block,
  -- if its condition is ‘False’.
  guard (input /= "stop")
  pure input

Read и Show подходят для простых программ, особенно когда вы изучаете Haskell, но в больших приложениях полезно использовать их в основном для отладки ввода и вывода и read ввода, который вы уже подтверждено. Библиотеки синтаксического анализа и красивой печати предпочтительнее для более сложного синтаксического анализа и создания удобочитаемого вывода соответственно; megaparsec и prettyprinter - хорошие варианты по умолчанию в этой области.

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