data Func = Variable [Char] | Number Float | Plus Func Func | Pow Func Func | Minus Func | Mul Func Func | Div Func Func | Exp Func | Ln Func
instance Show Func where
show (Variable v) = v
show (Number n) = show n
show (Minus a) = "-" ++ show a
show (Plus a b) = "(" ++ show a ++ "+" ++ show b ++ ")"
show (Pow a b) = "(" ++ show a ++ "^" ++ show b ++ ")"
show (Mul a b) = "(" ++ show a ++ "*" ++ show b ++ ")"
show (Div a b) = "(" ++ show a ++ "/" ++ show b ++ ")"
show (Exp a) = "(e^" ++ show a ++ ")"
show (Ln a) = "ln(" ++ show a ++ ")"
diff :: Func -> Func -> Func
diff _ (Number _) = Number 0
diff (Variable v) (Variable v2) = if v == v2 then Number 1 else Number 0
diff var (Plus a b) = Plus (diff var a) (diff var b)
diff var (Minus a) = Minus (diff var a)
diff var (Mul a b) = Plus (Mul a (diff var b)) (Mul (diff var a) b)
diff var (Div a b) = Div (Plus (Mul (diff var a) b) (Minus (Mul a (diff var b)))) (Pow b (Number 2))
diff var m@(Exp a) = Mul (diff var a) m
diff var (Ln a) = Mul (diff var a) (Div (Number 1) a)
diff var (Pow a b) = diff var $ Exp $ Mul b $ Ln a
main = print $ diff (Variable "x") $ Ln $ Pow (Variable "x") (Number 2)