프로그래밍 언어 입문서는 화면에 “Hello World”를 출력하는 프로그램을 보여주는 것으로 설명을 시작하는 전통이 있습니다. 이 전통에 따라 하스켈 “Hello World” 프로그램을 소개하겠습니다.
main = putStrLn "Hello World!"
이 프로그램을 실행하려면 먼저 코드를 복사해서 HelloWorld.hs
파일을 만듭니다. 그런 다음에 runhaskell
명령을 이용해 프로그램을 실행합니다. runhaskell
은 GHC를 설치하면 함께 설치되는 프로그램으로 인자로 주어진 하스켈 프로그램을 곧바로 실행시켜 주기 때문에 하스켈을 스크립트 언어로 쓸 수 있게 해줍니다.
$ runhaskell HelloWorld.hs
Hello World!
ghc
컴파일러를 이용해서 실행 파일을 생성하는 것도 가능합니다.
$ ghc --make HelloWorld.hs
컴파일 후에 HelloWorld
(윈도에서는 HelloWorld.exe
)라는 실행 파일이 생성된 것을 확인할 수 있습니다. 실행하면 runhaskell HelloWorld.hs
를 했을 때와 마찬가지로 화면에 “Hello World!”를 출력하는 것을 보실 수 있습니다.
$ ./HelloWorld
Hello World!
추가로 같은 디렉토리에 HelloWorld.hi
와 HelloWorld.o
파일도 생성된 것을 볼 수 있는데, .hs
파일은 각 모듈을 따로 컴파일(separate compilation)을 하기 위한 인터페이스 파일이고, .o
파일은 해당 모듈을 컴파일한 오브젝트 파일입니다. 이에 대해서는 하스켈 모듈 시스템을 설명할 때 좀 더 자세히 설명하겠습니다.
이제 코드 내용을 살펴보겠습니다. 우선 main
은 하스켈 코드가 실행되는 시작점(entry point)입니다. 모든 하스켈 프로그램은 main
에서 시작해서 main
으로 끝나게 됩니다.
ghci
을 이용해서 main
을 타입을 확인하면 다음과 같습니다. 참고로 :l
명령을 이용하면 외부 파일을 ghci
로 로드할 수 있습니다. HelloWorld
를 인자로 주면 HelloWorld.hs
파일을 컴파일하여 ghci
로 로드합니다.
$ ghci
> :l HelloWorld
[1 of 1] Compiling Main ( HelloWorld.hs, interpreted )
Ok, modules loaded: Main.
> :t main
main :: IO ()
main
의 타입은 IO ()
라는 것을 알 수 있습니다. 여기서 ()
타입은 유닛(unit) 타입으로()
가 유일한 값입니다. 주로 유용한 리턴 값이 없을 때 사용하는 타입인데, C++이나 Java의 void
와 유사한 역할을 합니다. 다만, 하스켈의 ()
타입은 void
와 달리 리턴 값이 없는 것이 아니라 ()
타입의 유일한 값인 ()
을 리턴합니다. 타입과 값 모두 ()
이라는 심볼을 사용하는 것에 유의하시기 바랍니다.
> () -- 여기서 ()는 값입니다.
()
> :t () -- 여기서 ()는 타입입니다.
() :: ()
main
의 리턴 값은 ()
이 아니라 IO ()
인데, 여기서 IO
는 사이드 이펙트가 있는 함수라는 뜻입니다. 쉽게 말해, 화면에 입출력을 할 수 있는 함수는 ()
가 아닌 IO ()
타입으로 표시합니다. IO
타입에 대한 자세한 설명은 입출력(IO)에 대한 설명을 할 때 자세히 이야기하겠습니다.
putStrLn
의 타입은 String -> IO ()
입니다. 타입에 ->
가 포함되어 있으므로 함수임을 알 수 있습니다. 인자 타입은 String
이고 리턴 타입은 IO ()
입니다. putStrLn
은 문자열을 하나 받아서 화면에 출력하는 함수입니다. 화면에 문자열을 출력하는 것도 사이드 이펙트이기 때문에 리턴 타입이 ()
가 아닌 IO ()
임을 알 수 있습니다.
> :t putStrLn
putStrLn :: String -> IO ()
putStrLn "Hello World!"
의 타입은 String -> IO ()
타입 함수에 String
인자를 호출하였기 때문에 putStrLn
의 리턴 타입인 IO ()
가 됩니다. main
의 타입인 IO ()
와putStrLn "Hello World!"
의 타입이 같기 때문에 이 프로그램을 컴파일 에러 없이 정상적으로 컴파일이 됩니다.
Pingback: 하스켈 “Hello World” 프로그램 – 서광열의 하스켈 스쿨