module Chap07
where

{- 7.1 -}
    test01 = [1..5] == [1,2,3,4,5]

    test02 = [5..1] == []

    test03 = [1,3..9]  == [1,3,5,7,9]

    test04 = [9,8..5]  == [9,8,7,6,5]

    test05 = [9,8..11] == []

    geometric :: (Ord a, Num a) => a -> a -> a -> [a]
    geometric r m n | m > n     = []
                    | otherwise = m : geometric r (m*r) n

    test06 = geometric 2 1 10 == [1,2,4,8]

{- 7.2 -}
    test07 = [ n*n | n<-[1..5]]  == [1,4,9,16,25]

    comp n = [ n*n | even n ] 
    ifn  n = (if even n then [n*n] else [])
    test08 = comp 7 == ifn 7

    test09 = [ n*n | let n = 2 ] == [4]

    test10 = [ (m,n) | m<-[1..3], n<-[4,5] ] == 
             [ (1,4), (1,5), (2,4), (2,5), (3,4), (3,5)]

    test11 = [ n*n | n<-[1..10], even n ] == [4,16,36,64,100] 

    test12 = [ (m,n) | m<-[1..3], n<-[1..m] ] == 
             [ (1,1), (2,1), (2,2), (3,1), (3,2), (3,3)] 

    test13 = [ 27 | n<-[1..3]] == [27,27,27] 

    test14 = [ x | x<-[1..3], y<-[1..2]] == [1,1,2,2,3,3] 

{- 7.2.1 -}
    spaces :: Int -> String
    spaces n = [ ' ' | i<-[1..n]]

    test15 = spaces 5 == "     "

{- 7.2.2 -}
    isPrime :: Int -> Bool
    isPrime n | n > 1 = (factors n == [])
  		        where factors m = [ x | x<-[2..(m-1)], m `mod` x == 0 ]
    isPrime   _       =  False

    test16 = isPrime 13 == True
    test17 = isPrime 14 == False

{- 7.2.3 -}
    sqPrimes :: Int -> Int -> [Int]
    sqPrimes m n = [ x*x | x<-[m..n], isPrime x ]

    test18 = sqPrimes 2 10 == [4,9,25,49]

    sqPrimes' :: Int -> Int -> [Int]
    sqPrimes' m n = map (\x -> x*x) (filter isPrime [m..n])

    test19 = sqPrimes' 2 10 == sqPrimes 2 10

{- 7.2.4 -}
    doublePos5 :: [Int] -> [Int]
    doublePos5 xs = [ 2*x | x<-xs, 0 < x ]

    test20 = doublePos [-1,0,1,2] == [2,4]

{- 7.2.5 -}
    superConcat :: [[[a]]] -> [a]
    superConcat xsss = [ x | xss<-xsss, xs<-xss, x<-xs ]
 
    hithere1 = [ ["hi ","there "],["world"],["!"],[]] 
    hithere2 = "hi there world!"

    test21 = superConcat hithere1 == hithere2

    superConcat' :: [[[a]]] -> [a]
    superConcat' = concat . map concat

    test22 = superConcat' hithere1 == superConcat hithere1

{- 7.2.6 -}
    positions :: Eq a => [a] -> a -> [Int]
    positions xs x = [ i | (i,y)<-zip [1..length xs] xs, x == y]

    position :: Eq a => [a] -> a -> Int 
    position xs x = head ( positions xs x ++ [0] )

    test23 = positions [10,30,30,40] 30 == [2,3]
    test24 = positions [10,30,30,40] 50 == []
    test25 = position  [10,30,30,40] 40 == 4
