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
data Expr = Num Int | Expr `Plus` Expr | Expr `Minus` Expr | Expr `Mul` Expr | Expr `Div` Expr | Var String | Count deriving Show exp1 = (Num 1) `Plus` (Num 2) exp2 = (Num 4) `Minus` (Num 3) exp3 = exp1 `Mul` (Num 5) newtype IdM a = I a deriving Show runIdM (I x) = x instance Monad IdM where I x >>= k = k x return x = I x evalI :: Expr -> IdM Int evalI (Num i) = return i evalI (e1 `Plus` e2) = do v1 <- evalI e1 v2 <- evalI e2 return (v1+v2) evalI (e1 `Minus` e2) = do v1 <- evalI e1 v2 <- evalI e2 return (v1+v2) evalI (e1 `Mul` e2) = do v1 <- evalI e1 v2 <- evalI e2 return (v1+v2) evalI (e1 `Div` e2) = do v1 <- evalI e1 v2 <- evalI e2 return (v1 `div` v2) runMaybe (Just x) = x evalM :: Expr -> Maybe Int evalM (Num i) = return i evalM (e1 `Plus` e2) = do v1 <- evalM e1 v2 <- evalM e2 return (v1+v2) evalM (e1 `Minus` e2) = do v1 <- evalM e1 v2 <- evalM e2 return (v1+v2) evalM (e1 `Mul` e2) = do v1 <- evalM e1 v2 <- evalM e2 return (v1+v2) evalM (e1 `Div` e2) = do v1 <- evalM e1 v2 <- evalM e2 if v2 == 0 then fail "Division by zero" else return (v1 `div` v2) type Env = [(String,Int)] lookupE :: String -> Env -> Maybe Int lookupE x = \env -> case [v | (y,v) <- env, y == x] of [] -> fail ("Free variable: " ++ x) v:_ -> return v evalE :: Expr -> Env -> Maybe Int evalE (Num i) = \env -> return i evalE (e1 `Plus` e2) = \env -> do v1 <- evalE e1 env v2 <- evalE e2 env return (v1+v2) evalE (e1 `Minus` e2) = \env -> do v1 <- evalE e1 env v2 <- evalE e2 env return (v1+v2) evalE (e1 `Mul` e2) = \env -> do v1 <- evalE e1 env v2 <- evalE e2 env return (v1+v2) evalE (e1 `Div` e2) = \env -> do v1 <- evalE e1 env v2 <- evalE e2 env if v2 == 0 then fail "Division by zero" else return (v1 `div` v2) evalE (Var x) = \env -> lookupE x env newtype Reader r a = R (r -> Maybe a) bindR :: Reader r a -> (a -> Reader r b) -> Reader r b (R ma) `bindR` f = R (\ r -> ma r >>= \ a -> case f a of R f' -> f' r) runReader :: Reader r a -> r -> Maybe a runReader (R r) e = r e lookupR :: String -> Reader Env Int lookupR x = R $ \env -> case [v | (y,v) <- env, y == x] of [] -> fail ("Free variable: " ++ x) v:_ -> return v instance Monad (Reader r) where return a = R (\ _ -> return a) (>>=) = bindR fail s = R (\ _ -> fail s) evalR :: Expr -> Reader Env Int evalR (Num i) = return i evalR (e1 `Plus` e2) = do v1 <- evalR e1 v2 <- evalR e2 return (v1+v2) evalR (e1 `Minus` e2) = do v1 <- evalR e1 v2 <- evalR e2 return (v1+v2) evalR (e1 `Mul` e2) = do v1 <- evalR e1 v2 <- evalR e2 return (v1+v2) evalR (e1 `Div` e2) = do v1 <- evalR e1 v2 <- evalR e2 if v2 == 0 then fail "Division by zero" else return (v1 `div` v2) evalR (Var x) = lookupR x newtype IntSt a = ISt (Int -> (a,Int)) instance Monad IntSt where return x = ISt (\s -> (x,s)) k >>= f = ISt (\s -> let ISt k' = k (x,s') = k' s ISt f' = f x in f' s') getInt :: IntSt Int getInt = ISt (\s -> (s,s)) putInt :: Int -> IntSt () putInt x = ISt (\s -> ((),x)) runIntSt :: IntSt a -> Int -> a runIntSt f s = let ISt f' = f in fst (f' s) inc :: IntSt Int inc = getInt >>= \i -> putInt (i+1) >> return i evalS :: Expr -> IntSt Int evalS (Num i) = return i evalS (e1 `Plus` e2) = do v1 <- evalS e1 v2 <- evalS e2 return (v1+v2) evalS (e1 `Minus` e2) = do v1 <- evalS e1 v2 <- evalS e2 return (v1+v2) evalS (e1 `Mul` e2) = do v1 <- evalS e1 v2 <- evalS e2 return (v1+v2) evalS (e1 `Div` e2) = do v1 <- evalS e1 v2 <- evalS e2 return (v1 `div` v2) evalS Count = inc