-- Approximate the square root of $x to at least the accuracy of $eps -- collecting the steps in a list. squareRoot :: Double -> Double -> [Double] squareRoot x eps | x < 0.0 = error "Non real answer." | eps < 0.0 = error "Accuracy can't be more than perfect." | otherwise = loop [((1 + x) / 2)] where loop :: [Double] -> [Double] loop (y:t) | abs((y * y) - x) <= eps = y : t | otherwise = loop ((0.5*(y+(x/y))):y:t) -- Just the head of this list. -- I wonder if the compiler is capeable to optimize the list away ... wurzel :: Double -> Double -> Double wurzel x eps = head (squareRoot x eps) -- How many approximations does it take to reach $eps accuracy count :: Double -> Double -> Int count x eps = length (squareRoot x eps) sq :: Double -> Double sq x = x * x -- Trivial isn't it? data Point = P Double Double deriving Show add :: Point -> Point -> Point add (P x1 y1) (P x2 y2) = P (x1+x2) (y1+y2) distance :: Point -> Point -> Double distance (P x1 y1) (P x2 y2) = sqrt ((sq (x1 - x2)) + (sq (y1 - y2))) -- A shape has an area an can be moved. class Shape a where move :: a -> Point -> a area :: a -> Double -- Circles are shapes. data Circle = C Point Double deriving Show instance Shape Circle where move (C middle radius) delta = C (add middle delta) radius area (C middle radius) = pi * (sq radius) -- As are Triangles. data Triangle = T Point Point Point deriving Show instance Shape Triangle where move (T point1 point2 point3) delta = T (add point1 delta) (add point2 delta) (add point3 delta) area (T point1 point2 point3) = sqrt (s * (s - a) * (s - b) * (s - c)) where s = (a + b + c) / 2 a = distance point1 point2 b = distance point2 point3 c = distance point3 point1 -- and Rectangles. data Rectangle = R Point Point deriving Show instance Shape Rectangle where move (R p1 p2) d = R (add p1 d) (add p2 d) area (R (P x1 y1) (P x2 y2)) = abs((x1 - x2) * (x1 - y2)) -- Bits are Zero or One. data Bit = Zero | One deriving (Eq, Show) -- Encode an Int as a Bit. enc1 :: Int -> Bit enc1 x | x == 0 = Zero | x /= 0 = One -- Decode a Bit to an Int. dec1 :: Bit -> Int dec1 x | x == Zero = 0 | x == One = 1 -- Convert from one datatype to an other by replaceing -- occurances of x with occurances y. replace :: (Eq a) => [(a,b)] -> a -> b replace [ ] _ = error "Undefined replacement" replace ((a, b) : xs) x | a == x = b | otherwise = replace xs x -- Pretty selfexplaining isn't it? encode :: Int -> [Bit] encode n | n < 0 = error "Can't convert negative numbers." | otherwise = convert n [] where convert :: Int -> [Bit] -> [Bit] convert 0 l = l convert n l = convert (floor (fromIntegral n / 2)) ((enc1 (mod n 2)):l) decode :: [Bit] -> Int decode l = foldl (\sum bit -> 2 * sum + (dec1 bit)) 0 l display :: [Bit] -> String display = map (replace [(Zero, '0'), (One, '1')])