{-# LANGUAGE GADTs #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE InstanceSigs #-}
module Lessons.Lesson11 where
import Control.Exception
import Control.DeepSeq
foo :: Integer
foo :: Integer
foo = String -> Integer
forall a. HasCallStack => String -> a
error String
"Oops"
c :: Exception e => IO (Either e Integer)
c :: forall e. Exception e => IO (Either e Integer)
c = IO Integer -> IO (Either e Integer)
forall e a. Exception e => IO a -> IO (Either e a)
try (Integer -> IO Integer
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> Integer
forall a. HasCallStack => String -> a
error String
"Ooops"))
eager :: [Integer]
eager :: [Integer]
eager = [Integer
1,Integer
2,Integer
3,Integer
4, String -> Integer
forall a. HasCallStack => String -> a
error String
"oj"]
lazy :: [Integer]
lazy :: [Integer]
lazy = Int -> [Integer] -> [Integer]
forall a. Int -> [a] -> [a]
take Int
2 [Integer
1,Integer
2,Integer
3,Integer
4, String -> Integer
forall a. HasCallStack => String -> a
error String
"ooops"]
lazy' :: Int
lazy' :: Int
lazy' = [Any] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [String -> Any
forall a. HasCallStack => String -> a
error String
"ooops"]
lazy'' :: [Integer]
lazy'' :: [Integer]
lazy'' = Int -> [Integer] -> [Integer]
forall a. Int -> [a] -> [a]
take Int
1 [String -> Integer
forall a. HasCallStack => String -> a
error String
"ooops"]
first :: Int -> [Integer]
first :: Int -> [Integer]
first Int
n = Int -> [Integer] -> [Integer]
forall a. Int -> [a] -> [a]
take Int
n [Integer
1..]
data Expr = Lit Integer
| Add Expr Expr
| Mul Expr Expr
| Neg Expr
deriving Int -> Expr -> ShowS
[Expr] -> ShowS
Expr -> String
(Int -> Expr -> ShowS)
-> (Expr -> String) -> ([Expr] -> ShowS) -> Show Expr
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Expr -> ShowS
showsPrec :: Int -> Expr -> ShowS
$cshow :: Expr -> String
show :: Expr -> String
$cshowList :: [Expr] -> ShowS
showList :: [Expr] -> ShowS
Show
prog1 :: Expr
prog1 :: Expr
prog1 = Expr -> Expr
Neg (Expr -> Expr -> Expr
Add (Integer -> Expr
Lit Integer
5) (Expr -> Expr -> Expr
Add (Integer -> Expr
Lit Integer
4) (Integer -> Expr
Lit Integer
6)))
eval :: Expr -> Integer
eval :: Expr -> Integer
eval (Lit Integer
i) = Integer
i
eval (Add Expr
e1 Expr
e2) = (Expr -> Integer
eval Expr
e1) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ (Expr -> Integer
eval Expr
e2)
eval (Mul Expr
e1 Expr
e2) = (Expr -> Integer
eval Expr
e1) Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* (Expr -> Integer
eval Expr
e2)
eval (Neg Expr
e) = - (Expr -> Integer
eval Expr
e)
print' :: Expr -> String
print' :: Expr -> String
print' (Lit Integer
i) = Integer -> String
forall a. Show a => a -> String
show Integer
i
print' (Add Expr
e1 Expr
e2) = (Expr -> String
print' Expr
e1) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" + " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Expr -> String
print' Expr
e2)
print' (Mul Expr
e1 Expr
e2) = (Expr -> String
print' Expr
e1) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" * " String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Expr -> String
print' Expr
e2)
print' (Neg Expr
e) = String
"-(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ (Expr -> String
print' Expr
e) String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
")"
class Expression repr where
lit :: Integer -> repr
add :: repr -> repr -> repr
instance Expression Integer where
lit :: Integer -> Integer
lit :: Integer -> Integer
lit Integer
i = Integer
i
add :: Integer -> Integer -> Integer
add :: Integer -> Integer -> Integer
add Integer
a Integer
b = Integer
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
b
instance Expression String where
lit :: Integer -> String
lit :: Integer -> String
lit = Integer -> String
forall a. Show a => a -> String
show
add :: String -> String -> String
add :: String -> ShowS
add String
a String
b = String
a String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
" + " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
b
class ExpressionMul repr where
mul :: repr -> repr -> repr
instance ExpressionMul Integer where
mul :: Integer -> Integer -> Integer
mul :: Integer -> Integer -> Integer
mul Integer
a Integer
b = Integer
a Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
* Integer
b
prog2 :: Integer
prog2 :: Integer
prog2 = Integer -> Integer -> Integer
forall repr. ExpressionMul repr => repr -> repr -> repr
mul (Integer -> Integer
forall repr. Expression repr => Integer -> repr
lit Integer
6) (Integer -> Integer -> Integer
forall repr. Expression repr => repr -> repr -> repr
add (Integer -> Integer
forall repr. Expression repr => Integer -> repr
lit Integer
5) (Integer -> Integer -> Integer
forall repr. Expression repr => repr -> repr -> repr
add (Integer -> Integer
forall repr. Expression repr => Integer -> repr
lit Integer
4) (Integer -> Integer
forall repr. Expression repr => Integer -> repr
lit Integer
6)))
prog3 :: String
prog3 :: String
prog3 = String -> ShowS
forall repr. Expression repr => repr -> repr -> repr
add (Integer -> String
forall repr. Expression repr => Integer -> repr
lit Integer
5) (String -> ShowS
forall repr. Expression repr => repr -> repr -> repr
add (Integer -> String
forall repr. Expression repr => Integer -> repr
lit Integer
4) (Integer -> String
forall repr. Expression repr => Integer -> repr
lit Integer
6))
data GExpr a where
GInt :: Integer -> GExpr Integer
GBool :: Bool -> GExpr Bool
GAdd :: GExpr Integer -> GExpr Integer -> GExpr Integer
GEq :: Eq a => GExpr a -> GExpr a -> GExpr Bool
evalG :: GExpr a -> a
evalG :: forall a. GExpr a -> a
evalG (GInt Integer
i) = a
Integer
i
evalG (GBool Bool
b) = a
Bool
b
evalG (GAdd GExpr Integer
e1 GExpr Integer
e2) = GExpr a -> a
forall a. GExpr a -> a
evalG GExpr a
GExpr Integer
e1 a -> a -> a
forall a. Num a => a -> a -> a
+ GExpr a -> a
forall a. GExpr a -> a
evalG GExpr a
GExpr Integer
e2
evalG (GEq GExpr a
e1 GExpr a
e2) = GExpr a -> a
forall a. GExpr a -> a
evalG GExpr a
e1 a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== GExpr a -> a
forall a. GExpr a -> a
evalG GExpr a
e2