2013-06-28 4 views
14

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

main = do x <- readFile "/tmp/foo.txt" 
     putStr x 

Но сейчас я хотел бы путь быть аргументом, поэтому я попытался следующий

main s = do x <- readFile s 
     putStr x 

Это не делает Работа. Я вижу следующее сообщение об ошибке:

Couldn't match expected type `IO t0' 
      with actual type `FilePath -> IO()' 
In the expression: main 
When checking the type of the function `main' 

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

+2

Очень простой, но также очень действительный вопрос. Я удивлен, что раньше этого не спрашивали, но не нашел точного дубликата с быстрым поиском. [Этот вопрос] (http://stackoverflow.com/questions/8747780/inputting-data-with-haskell/) очень похож. –

ответ

15

Haskell report specifies, что функция main всегда имеет тип IO t, (для некоторых типов t, который будет проигнорирован) и, следовательно, никогда не принимает нормальные аргументы функции, так что это не правильный подход.

Вы ищете функции getArgs (для которого вы должны импортировать модуль System.Environment возвращает аргументы, передаваемые в программу в виде списка String с

Так что ваш код будет выглядеть следующим образом:..

import System.Environment 
main = do 
    args <- getArgs 
    case args of 
     [file] -> do 
     x <- readFile file 
     putStr x 
     _ -> putStrLn "Wrong number of arguments" 
+1

Хорошо, и теперь я могу назвать главную функцию следующим: main "/tmp/foo.txt"? – user2533428

+1

Нет, вы можете скомпилировать свою программу ('ghc main.hs'), а затем запустить ее как' ./main/tmp/foo.txt'. – Koterpillar

+3

Да, вы можете, но оставить круглую скобку, т. Е. Написать ': main/tmp/foo.txt' (так же, как вы будете передавать параметры командной строки). – Long

9

в Haskell аргументы не приводятся к основной функции из-за способа Haskell связывает свое начало и оставаться последовательным. Вы должны использовать System.Environment.getArgs.

В частности, поскольку Haskell является чистым функциональным языком, main является монадическим действием, которое организует вычисления с побочным эффектом, выполняемые программным обеспечением - результат, вычисленный main, отбрасывается, поскольку на функциональных языках вы отсоединяетесь от среды w.r.t. вычислений и только взаимодействовать с ним как побочный эффект.

Пример
import System.Environment 

main = do x <- getArgs; print x 

Это будет печатать все, что вы вводите в командной строке.

The Haskell wiki has an excellent tutorial on the topic.