Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
-- different list functions recursively and as foldrs
{-
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr c n [] = n
foldr c n (a : as) = c a (foldr c n as)
-}
myConcat :: [[a]] -> [a]
{-
myConcat [] = []
myConcat (as : ass) = as ++ myConcat ass
-}
myConcat = foldr (++) []
myElem :: Eq a => a -> [a] -> Bool
{-
myElem e [] = False
myElem e (a : as) = if e == a then True else myElem e as
-}
myElem e = foldr (\ a b -> if e == a then True else b) False
nth :: [a] -> Int -> a
{-
nth (a : as) n = if n == 0 then a else nth as (n - 1)
-}
nth = foldr (\ a f n -> if n == 0 then a else f (n - 1))
(\ _ -> error "bad case")
-- Eratosthenes' sieve
sieve :: [Int]
sieve = sieve' [2..]
sieve' :: [Int] -> [Int]
sieve' (n : ns) = n : sieve' [ m | m <- ns , m `mod` n /= 0 ]
-- cf this non-recursive protosieve
protosieve (n : ns) = n : [ m | m <- ns, m `mod` n /= 0 ]
--protosieve (n : ns) = n : filter (\ m -> m `mod` n /= 0) ns
-- defining types
-- some simple non-recursive datatypes
-- data Bool = True | False
data Answer = Yes | No | Unknown
flip :: Answer -> Answer
flip Yes = No
flip No = Yes
flip Unknown = Unknown
data Shape = Circle Float | Rect Float Float
square :: Float -> Shape
square n = Rect n n
area :: Shape -> Float
area (Circle r) = pi * r ^ 2
area (Rect x y) = x * y
-- maybe types
{-
data Maybe a = Nothing | Just a
-}
{-
return :: a -> Maybe a
return a = Just a
(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
Nothing >>= _ = Nothing
Just a >>= f = f a
-}
{-
class Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
instance Monad Maybe where
return a = Just a
Nothing >>= _ = Nothing
Just a >>= f = f a
-}
-- further to some recursive datatypes
-- (unary) natural numbers
data Nat = Zero | Succ Nat
nat2int :: Nat -> Int
nat2int Zero = 0
nat2int (Succ n) = 1 + nat2int n
int2nat :: Int -> Nat
int2nat 0 = Zero
int2nat (i+1) = Succ (int2nat i)
addN :: Nat -> Nat -> Nat
addN Zero n = n
addN (Succ m) n = Succ (addN m n)
multN :: Nat -> Nat -> Nat
multN Zero n = Zero
multN (Succ m) n = addN m (multN m n)
foldN :: (b -> b) -> b -> Nat -> b
foldN s z Zero = z
foldN s z (Succ n) = s (foldN s z n)
{-
-- alternatively, naturals can be used as a type synonym
type Nat = [()]
zero :: Nat
zero = []
suck :: Nat -> Nat
suck n = () : n
addNat = (++)
-}
-- binary naturals
data Bin = B0 Bin | B1 Bin | Null
--type Bin = [Bool]
bin2int :: Bin -> Int
bin2int n = fst (bin2int' n)
bin2int' :: Bin -> (Int, Int)
bin2int' Null = (0, 0)
bin2int' (B0 n) = (n', ell + 1)
where (n', ell) = bin2int' n
bin2int' (B1 n) = (2 ^ ell + n', ell + 1)
where (n', ell) = bin2int' n
-- think of further functions for binary naturals
-- base-n naturals
-- arithmetic expressions
-- variable environments
{-
type Env = [(String, Int)]
lkp :: String -> Env -> Maybe Int
lkp x [] = Nothing
lkp x ((x',n) : xs) = if x == x' then Just n else lkp x xs
empty :: Env
empty = []
update :: String -> Int -> Env -> Env
update x n xs = (x, n) : xs
-}
type Env = String -> Maybe Int
lkp :: String -> Env -> Maybe Int
lkp x env = env x
empty :: Env
empty _ = Nothing
update :: String -> Int -> Env -> Env
update x n env = env'
where env' y | x == y = Just n
| otherwise = env y
-- expressions
data Expr = Var String
| Num Int
| Add Expr Expr
| Mul Expr Expr deriving Show
size :: Expr -> Int
size (Num n) = 1
size (Add e0 e1) = 1 + size e0 + size e1
size (Mul e0 e1) = 1 + size e0 + size e1
eval :: Expr -> Env -> Maybe Int
eval (Var x) env = lkp x env
eval (Num n) env = Just n
eval (Add e0 e1) env = case eval e0 env of
Nothing -> Nothing
Just n0 -> case eval e1 env of
Nothing -> Nothing
Just n1 -> Just (n0 + n1)
eval (Mul e0 e1) env = case eval e0 env of
Nothing -> Nothing
Just n0 -> if n0 == 0 then Just 0 else case eval e1 env of
Nothing -> Nothing
Just n1 -> Just (n0 * n1)
mulUp n = Mul (Num n) (mulUp (n+1))
-- define fold for this recursive datatype
-- example of non-structural recursion
gcd m n = if m >= n then gcd' m n else gcd' n m
gcd' m n = if m `mod` n == 0 then n else gcd' n (m `mod` n)
-- some basic type classes
{-
class Functor f where
fmap :: (a -> b) -> (f a -> f b)
class Monad m where
return :: a -> m a
(>>=) :: m a -> (a -> m b) -> m b
(>>) :: m a -> m b -> m b
fail :: String -> m a
-- Minimal complete definition: (>>=), return
p >> q = p >>= \ _ -> q
fail s = error s
-}