Функция Haskell типа: Строка IO-> Строка

Почему текстовые файлы управляют? Из-за теста McIlroy. Жизненно важно иметь вывод одной программы быть приемлемым как исходный код для другого, и текстовые файлы являются самой простой вещью, которая работает.

35
задан R. Martinho Fernandes 4 November 2009 в 17:48
поделиться

4 ответа

Вы можете легко написать функцию, которая вызывает действие readFile и передает результат вашей индексной функции.

readAndIndex fileName = do
    text <- readFile fileName
    return $ index text

Однако монада ввода-вывода портит все, что ее использует, поэтому эта функция имеет тип:

readAndIndex :: FilePath -> IO [(String, [Integer])]
42
ответ дан 27 November 2019 в 06:37
поделиться

Ну, вы не можете избавиться от монадной части IO в IO String . Это означает, что вам нужно будет заставить вашу функцию возвращать IO [(String, [Integer])] .

Я рекомендую узнать больше о монадах, но пока вы можете обойтись без liftM функция:

liftM index (readFile "input.txt")

liftM имеет следующую сигнатуру:

liftM :: Monad m => (a -> b) -> m a -> m b

Она принимает немонадическую функцию и преобразует ее в монадическую функцию.

16
ответ дан 27 November 2019 в 06:37
поделиться
fmap index $ readFile "input.txt"

или

readFile "input.txt" >>= return . index

Вы можете изучить монаду и функторы

9
ответ дан 27 November 2019 в 06:37
поделиться

Существует очень веская причина, по которой нет такой функции.

В Haskell есть понятие функциональная чистота. Это означает, что функция всегда будет возвращать один и тот же результат при вызове с одинаковыми параметрами. Единственное место, где разрешен ввод-вывод, находится внутри монады ввода-вывода.

Если бы была * функция

index :: IO String -> String

, тогда мы могли бы внезапно выполнять действия ввода-вывода где угодно , вызывая, например :

index (launchMissiles >> deleteRoot >> return "PWNd!")

Функциональная чистота - это очень полезная функция, которую мы не хотим терять, поскольку она позволяет компилятору гораздо более свободно переупорядочивать и встраивать функции, их можно переносить на разные ядра без изменения семантики, а также дает программисты - чувство безопасности, потому что если вы можете знать, что функция может, а что нет, по ее типу.

* Собственно там есть такая функция. Он называется unsafePerformIO и называется так по очень, очень веским причинам. Не используйте его, если вы не уверены на 100% в том, что делаете!

29
ответ дан 27 November 2019 в 06:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: