### 函数程序设计实验一：分式 wu-kan

--import Test.QuickCheck
module MyFraction where
Fraction=(Integer,Integer)

--分式化简
ratreduction::Fraction->Fraction
ratreduction(x,y)=(div x g,div y g)where g=gcd x y

--加法
ratplus::Fraction->Fraction->Fraction
ratplus(a,b)(c,d)=ratreduction(a*d+b*c,b*d)

--减法，调用加法实现
ratminus::Fraction->Fraction->Fraction
ratminus(a,b)(c,d)=ratplus(a,b)(-c,d)

--乘法
rattimes::Fraction->Fraction->Fraction
rattimes(a,b)(c,d)=ratreduction(a*c,b*d)

--除法，调用乘法实现
ratdiv::Fraction->Fraction->Fraction
ratdiv(a,b)(c,d)=rattimes(a,b)(d,c)

--取整
ratfloor::Fraction->Integer
ratfloor(a,b)=div a b

--转成浮点
ratfloat::Fraction->Float
ratfloat(a,b)=fromInteger a/fromInteger b

--判断相等
rateq::Fraction->Fraction->Bool
rateq(a,b)(c,d)=a*d==b*c

--重载运算符
(<+>)::Fraction->Fraction->Fraction
(a,b)<+>(c,d)=ratplus(a,b)(c,d)

(<->)::Fraction->Fraction->Fraction
(a,b)<->(c,d)=ratminus(a,b)(c,d)

(<-*->)::Fraction->Fraction->Fraction
(a,b)<-*->(c,d)=rattimes(a,b)(c,d)

(</>)::Fraction->Fraction->Fraction
(a,b)</>(c,d)=ratdiv(a,b)(c,d)

(<==>)::Fraction->Fraction->Bool
(a,b)<==>(c,d)=rateq(a,b)(c,d)

--确定运算优先级
infixl 6 <-*->,</>
infixl 5 <+>,<->
infixl 4 <==>

{-
--检查任意分数+(0,1)之后仍然等于其本身
prop_ratplus_unit :: Fraction -> Property
prop_ratplus_unit (a,b) = b > 0 ==>(a, b) <+> (0,1) <==> (a, b)

--检查任意分数加上相反数之后为0
prop_ratplus_inv :: Fraction -> Property
prop_ratplus_inv (a,b) = b > 0 ==>(a, b) <+> (-a,b) <==> (0, 1)

--检查任意非零分数乘上倒数之后为1
prop_rattimes_inv :: Fraction -> Property
prop_rattimes_inv (a,b) = a/=0&&b > 0 ==>(a, b) <-*-> (b,a) <==> (1, 1)

-- 检查乘法分配律
prop_rattimes_plus_distr :: Fraction -> Fraction -> Fraction ->Property
prop_rattimes_plus_distr (a,b) (c,d) (e,f) = b > 0 && d > 0 && f > 0 ==> (a,b) <-*-> ((c,d) <+> (e,f)) <==> ((a,b) <-*-> (c,d)) <+> ((a,b) <-*-> (e,f))
-}