data List a = Nil | Cons a (List a) deriving Show
foldList :: (a -> b -> b) -> b -> List a -> b
foldList _ g Nil = g
foldList f g (Cons x xs) = f x (foldList f g xs)
mapList :: (a -> b) -> List a -> List b
mapList f = foldList (\x xs -> Cons (f x) xs) Nil
-- infinite list
from :: Integer -> [Integer]
from n = n : from (n+1)
nats = from 0
myTake :: Int -> [a] -> [a]
myTake 0 _ = []
myTake _ [] = []
myTake (n+1) (x:xs) = x : myTake n xs
dropMult :: Integer -> [Integer] -> [Integer]
dropMult x xs = x : filter (\y -> y `mod` x /= 0) xs
dropAll :: [Integer] -> [Integer]
dropAll (x:xs) = dropMult x (dropAll xs)
primes :: [Integer]
primes = dropAll (from 2)
-- infinite data objects
ones = 1 : ones
nats2 = 0 : map (\x -> x + 1) nats2
-- Hamming list
mer :: [Integer] -> [Integer] -> [Integer]
mer (x:xs) (y:ys) | x < y = x : mer xs (y:ys)
| x == y = x : mer xs ys
| True = y : mer (x:xs) ys
mer3 :: [Integer] -> [Integer] -> [Integer] -> [Integer]
mer3 xs ys zs = mer (mer xs ys) zs
ham = 1 : mer3 (map (2*) ham) (map (3*) ham) (map (7*) ham)
-- INPUT / OUTPUT
putString :: String -> IO ()
putString [] = return ()
putString (x:xs) = putChar x >> putString xs
getS :: IO String
getS = getChar >>= \x -> if x == '\n' then return [] else (getS >>= \xs -> return (x:xs))
gets :: IO String
gets = do
x <- getChar
if x == '\n' then return [] else do
xs <- gets
return (x:xs)
gets2 :: IO String
gets2 = getChar >>= \x -> (if x == '\n' then return [] else gets2 >>= \xs -> return (x:xs))
main :: IO ()
main = do
putString "Please enter your name:"
name <- gets
putString ("Hello " ++ name ++ "!")