Синтаксис Haskell, привязка содержимого файла к переменным

Основная идея кода заключается в том, что я загружаю выражение из файла, который имеет только 100 + a + (x ^ 2) строку, такую как 100 + a + (x ^ 2)

Я хочу загрузить его в функцию и проверить, нормально ли это (так что это не так )) + 5 2 a **). Сначала я хочу сказать, что знаю, что мои чеки не покрывают всех типов ошибок, но мы должны проверять только некоторые ошибки. Сначала вот код

main = do 
 contents <- readFile "file.txt" 
 let stringToCheck <- line contents
 checkIfProper filter (/=' ') stringToCheck

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

Мой первый вопрос заключается в начале основной загрузки из файла file.txt, у этого файла есть только 1 строка, и я беру его в stringToCheck, а затем я хочу использовать на нем фильтр, чтобы удалить все пробелы, но это не сработает. Если я вызываю фильтр на строку, которую я записываю в настоящий момент, это хорошо, но когда я загружаю его из файла, у него возникают проблемы, я думаю, что я не правильно беру строку, чтобы это сделать?

Как правильно взять строку из файла и использовать ее как переменную в другой функции?

1 ответ

main = do 
 contents <- readFile "file.txt"

Пока все прекрасно. Вы прочитали файл в IO и использовали синтаксис do -block с <- правильно. Для всего contents представляет собой переменную String, содержащую содержимое файла.

let stringToCheck <- line contents

Здесь вам не нужен синтаксис специального назначения: в этот момент, как я уже сказал, contents является "чистым" значением, поэтому все, что вы используете для него, чисто функционально, и вы можете использовать обычный =. Это всегда делалось в блоках let. Так...

let stringToCheck = line contents

Ну, это не работает, потому что нет функции line. Существуют lines, которые разбивают текст в списке строк, каждый из которых представляет строку; для извлечения первого использования

let stringToCheck = head $ lines contents

но если файл имеет только одну строку, это эквивалентно просто stringToCheck = contents.

checkIfProper filter (/=' ') stringToCheck

Теперь предположим, что вы имеете в виду checkIfProper (filter (/=' ') stringToCheck): функция checkIfProper принимает только один аргумент, но если вы просто выписываете составное выражение, которое неверно рассматривается как пара различных аргументов, т. checkIfProper filter (/=' ') stringToCheck самом деле означает, что на не-точных языках будет записан checkIfProper(filter, (/=' '), stringToCheck). Я не думаю, что ты имеешь в виду это!

Идиоматический способ записи в Haskell

checkIfProper $ filter (/=' ') stringToCheck

В результате main checkIfProper все еще не может компилироваться: результат checkIfProper должен иметь тип IO() поэтому вы можете просто добавить его в блок do как в main, но, по-видимому, он имеет тип String → Bool. Возможно, вы хотите, чтобы результат был распечатан, что было сделано с

print . checkIfProper $ filter (/=' ') stringToCheck

Если вы не знакомы . и $: вы можете прочитать выражение типа

f . g . h $ x + y

в виде

f (g (h (x + y)))

licensed under cc by-sa 3.0 with attribution.