-- Elm Rational number case study similar to Haskell and Lua -- Rational example case studies (with Rational Core). -- This version does not handle (x,0) error case. -- CSci 450, Fall 2016 -- 2016-11-14: H. Conrad Cunningham import Html exposing (..) -- Rational number alias type alias Rat = (Int, Int) -- First-order Operations negRat : Rat -> Rat negRat x = makeRat (0 - (numer x)) (denom x) -- negation? addRat : Rat -> Rat -> Rat addRat x y = makeRat (numer x * denom y + numer y * denom x) (denom x * denom y) subRat : Rat -> Rat -> Rat subRat x y = makeRat (numer x * denom y - numer y * denom x) (denom x * denom y) mulRat : Rat -> Rat -> Rat mulRat x y = makeRat (numer x * numer y) (denom x * denom y) divRat : Rat -> Rat -> Rat divRat x y = makeRat (numer x * denom y) (denom x * numer y) eqRat : Rat -> Rat -> Bool eqRat x y = (numer x) * (denom y) == (numer y) * (denom x) --- Core Operations makeRat : Int -> Int -> Rat makeRat x y = if x == 0 then (0, 1) else let xx = (signum y) * x yy = abs1 y d = gcd1 xx yy in (xx // d, yy // d) numer : Rat -> Int numer (x,_) = x denom : Rat -> Int denom (_,y) = y showRat : Rat -> String showRat x = toString (numer x) ++ "/" ++ toString (denom x) --- Rational Utilities signum : Int -> Int signum n = if n == 0 then 0 else if n > 0 then 1 else -1 -- could just use abs from library abs1 : Int -> Int abs1 n = if n >= 0 then n else -n gcd1 : Int -> Int -> Int gcd1 x y = let gcdaux : Int -> Int -> Int gcdaux x y = if y == 0 then x else gcdaux y (x % y) in gcdaux (abs1 x) (abs1 y) -- Simple Display Functions newline = br [] [] displayLines : List String -> List (Html msg) displayLines ss = case ss of [] -> [] x :: xs -> text x :: newline :: displayLines xs display : List String -> Html msg display ls = p [] (displayLines ls) -- Some testing test1str = "showRat (mulRat (addRat (makeRat 1 2) (makeRat 6 8)) (makeRat 1 5)))" test1out = showRat (mulRat (addRat (makeRat 1 2) (makeRat 6 8)) (makeRat 1 5)) main = display [ test1str ++ " = " ++ test1out , "Done!" ]