GHC
Implementation of programming language HaskellGlasgow Haskell Compiler, usually referred to as GHC, is a cross-platform open-source compiler of Haskell. It is written in Haskell, except for the runtime system which is written in C and C—.
GHC implements the Haskell 98 dialect of the language as well as several extensions.
Examples:
Hello, World!:
Example for versions GHC 6.10.4module Main where
main = do
putStrLn "Hello, World!"
Factorial:
Example for versions GHC 6.10.4This example uses recursive factorial definition and consists of three major parts:
-
definition of
factorial
function, which takes one argument ofInteger
type (integer number of unlimited precision) and returns the same type. The function is defined recursively, and types of argument and return are given explicitly to avoid ambiguity. -
definition of
line
function, which prints the number and its factorial in required format. Use of
printf
command is the same as in C++. -
printing the numbers and their factorials themselves.
[0..16]
creates a list of numbers from 0 to 16, inclusive. Functionmap
applies first argument (line
function) to each element of second argument ([0..16]
list) and as a result creates a list of so-called “output actions” (which can be used as values in Haskell). To combine these actions in one we usesequence_
command, which is applied to a list of actions, executes first action from the list and recursively applies it to the tail of the list. But for simplicity, we usemapM_
, which combinesmap
andsequence_
.
module Main where
import Text.Printf
factorial :: Integer -> Integer
factorial 0 = 1
factorial n = n * factorial (n - 1)
line x = printf "%d! = %d\n" x $ factorial x
main = mapM_ line [0..16]
Fibonacci numbers:
Example for versions GHC 6.10.4This example uses one of the main Haskell features — lazy evaluations and infinite lists. Infinite list of Fibonacci numbers fibs
is defined using zipWith
function which applies its first argument (a function of two variables, in this case +
) to pairs of corresponding elements of second and third arguments (lists). tail fibs
returns tail of the list fibs
(i.e., all elements except for the first one). Thus first element of the list returned by zipWith
is a sum of first and second elements of list fibs
and becomes its third element.
module Main where
import Text.Printf
fibs :: [Int]
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
line n = printf "%d, " $ fibs !! n
main = do
sequence_ $ map line [1..16]
putStrLn "..."
Fibonacci numbers:
Example for versions GHC 6.10.4This example uses recursive definition of Fibonacci numbers via pairs of adjacent numbers in the sequence. Only first elements of the pairs are printed.
module Main where
import Text.Printf
fibNextPair :: (Int, Int) -> (Int, Int)
fibNextPair (x, y) = (y, x+y)
fibPair :: Int -> (Int, Int)
fibPair n
| n == 1 = (1, 1)
| otherwise = fibNextPair (fibPair (n-1))
line n = printf "%d, " $ (fst.fibPair) n
main = do
sequence_ $ map line [1..16]
putStrLn "..."
Factorial:
Example for versions GHC 6.10.4This example uses the Prelude function product
, which computes the product of a list of numbers. When the list is empty, it returns 1 (the multiplicative identity), so this works for 0 too.
module Main where
factorial :: Integer -> Integer
factorial n = product [1..n]
line x = putStrLn $ show x ++ "! = " ++ factorial x
main = mapM_ line [0..16]
Factorial:
Example for versions GHC 6.10.4This example performs a “fold” using the function foldl
(which is a left-fold, but since multiplication is associative, left fold and right fold are the same) to fold multiplication over the list [1..n]
. We provide the “initial value” 1, so that it will produce 1 when the list is empty.
module Main where
factorial :: Integer -> Integer
factorial n = foldl (*) 1 [1..n]
line x = putStrLn $ show x ++ "! = " ++ factorial x
main = mapM_ line [0..16]
Quadratic equation:
Example for versions GHC 6.10.4Haskell provides complex datatype. Function quadratic
accepts a list of complex numbers and returns a list of equation roots. Notation root sign
allows to generalize the notation of roots for two signs of square root.
module Main where
import Data.Complex
import System.IO (hFlush, stdout)
quadratic :: (Complex Double, Complex Double, Complex Double) -> [Complex Double]
quadratic (0, _, _) = []
quadratic (a, b, c)
| d == 0 = [root (+)]
| otherwise = [root (+), root (-)]
where d = b*b - 4*a*c
root sign = sign (-b) (sqrt d) / (2*a)
main = do
putStr "A = "
hFlush stdout
a <- readLn :: IO Double
putStr "B = "
hFlush stdout
b <- readLn :: IO Double
putStr "C = "
hFlush stdout
c <- readLn :: IO Double
print $ quadratic (realToFrac a, realToFrac b, realToFrac c)
Fibonacci numbers:
Example for versions GHC 6.10.4This is another example which uses lazy evaluation and a different, shorter form of producing output in required format.
main = putStrLn $ withDots $ join $ take 16 fibs
where fibs = 1 : 1 : zipWith (+) fibs (tail fibs)
join = foldl (\a b -> a ++ show b ++ ", " ) ""
withDots = (++ "...")
Comments
]]>blog comments powered by Disqus
]]>