CS计算机代考程序代写 Haskell {-# LANGUAGE ExistentialQuantification #-}

{-# LANGUAGE ExistentialQuantification #-}
{-|
Module : HaskellExercises01.Spec
Copyright : (c) Curtis D’Alves 2020
License : GPL (see the LICENSE file)
Maintainer : none
Stability : experimental
Portability : portable

Description:
Contains Quickcheck tests for Exercises01 and a main function that runs each tests and prints the results
-}
module Main where

import qualified Assign_1 as Student
import Data.Char
import Data.Fixed (mod’)
import Test.QuickCheck (quickCheck
,quickCheckResult
,quickCheckWithResult
,stdArgs
,maxSuccess
,Result(Success)
,within
,Testable)
import Test.Hspec
import Test.QuickCheck.Property (property)

——————————————————————————————-
— * QuickCheck Tests

— | Existential type wrapper for QuickCheck propositions, allows @propList@ to essentially
— act as a heterogeneous list that can hold any quickcheck propositions of any type
data QuickProp = forall prop . Testable prop =>
QuickProp { quickPropName :: String
, quickPropMark :: Int
, quickPropFunc :: prop
}

— | Boolean implication
(==>) :: Bool -> Bool -> Bool
x ==> y = (not x) || y
infixr 4 ==>

{- —————————————————————–
– sinTaylorProp
– —————————————————————–
– Description:
– Quickcheck property, tests if Student.cosTaylor is accurate
– enough by comparing to built-in Prelude cos. Call this using
– Test.QuickCheck, i.e
– > import Test.QuickCheck (quickCheck)
– > quickCheck sinTaylorProp
– —————————————————————–
– | Input | |
– | a’ | the value the taylor series is centered at |
– | h’ | incremental value used to compute x = a’ + h’ |
– —————————————————————–
– | Output | True iff | cos(x) – cosTaylor(x) | <= tolerance | - ----------------------------------------------------------------- -} sinTaylorProp :: Double -> Double -> Bool
sinTaylorProp a’ h’ =
let
— restrict -2*pi < a < 2*pi a = (a' `mod'` (2*pi)) -- restrict 0 < h < pi/8 h = (abs h' `mod'` (pi/8)) -- calculate a values using built-in cos cos_a = cos a sin_a = sin a -- use input a <= x < a + pi/4 for input x = a + h -- compare built-in cos to cosTaylor within a given tolerance sinRef = sin x sin_x = Student.sinTaylor a cos_a sin_a x tol = 1e-4 -- Passes test iff | cos(x) - cosTaylor(x) | <= tol in abs (sinRef - sin_x) <= tol {- ------------------------------------------------------------------------- - fmodProp - ------------------------------------------------------------------------- - Description: - Quickcheck property, tests if Student.fmod is accurate - enough by comparing to mod' from the Data.Fixed library. - Call this using Test.QuickCheck, i.e - > import Test.QuickCheck (quickCheck)
– > quickCheck fmodProp
– ————————————————————————-
– | Input | |
– | x’,y’ | Floating point inputs |
– ————————————————————————-
– | Output | True iff (x – rem) / y) is approximately a whole number|
– ————————————————————————-
-}
fmodProp :: Double -> Double -> Bool
fmodProp x y =
let
— if r is the correct remainder, w should be very close to a whole number
r = Student.fmod x y
w = (x – r) / y
— if w is almost a whole number, then d ~ 0.0
d = abs $ w – fromInteger (round w)
— we’ll allow for this much floating point error
tol = 1e-6
— passes test iff d <= tol, NOTE: y must be > 0 to avoid NaN
in (abs y < tol) || (d <= tol) {- ------------------------------------------------------------------------- - sinApproxProp - ------------------------------------------------------------------------- - Description: - Quickcheck property, tests if Student.sinApprox is accurate - enough by comparing to built-in sin from the Prelude. - Call this using Test.QuickCheck, i.e - > import Test.QuickCheck (quickCheck)
– > quickCheck sinApproxProp
– ————————————————————————-
– | Input | |
– | x’ | Floating point input |
– ————————————————————————-
– | Output | True iff sinApprox(x) ~ sin(x) |
– ————————————————————————-
-}
sinApproxProp :: Double -> Bool
sinApproxProp x =
let
— get value of sin for Prelude cos and Student sinApprox
sinRef = sin x
sin_x = Student.sinApprox x
— we’ll allow for this much margin of error
tol = 1e-2
— passes test iff | sin(x) – sinApprox(x) | <= tol in abs (sinRef - sin_x) <= tol {- ------------------------------------------------------------------------- - cosApproxProp - ------------------------------------------------------------------------- - Description: - Quickcheck property, tests if Student.cosApprox is accurate - enough by comparing to built-in cos from the Prelude. - Call this using Test.QuickCheck, i.e - > import Test.QuickCheck (quickCheck)
– > quickCheck cosApproxProp
– ————————————————————————-
– | Input | |
– | x’ | Floating point input |
– ————————————————————————-
– | Output | True iff cosApprox(x) ~ cos(x) |
– ————————————————————————-
-}
cosApproxProp :: Double -> Bool
cosApproxProp x =
let
— get value of cos for Prelude cos and Student cosApprox
cosRef = cos x
cos_x = Student.cosApprox x
— we’ll allow for this much margin of error
tol = 1e-2
— passes test iff | cos(x) – cosApprox(x) | <= tol in abs (cosRef - cos_x) <= tol {- ------------------------------------------------------------------------- - tanApproxProp - ------------------------------------------------------------------------- - Description: - Quickcheck property, tests if Student.tanApprox is accurate - enough by comparing to built-in tan from the Prelude. - Call this utang Test.QuickCheck, i.e - > import Test.QuickCheck (quickCheck)
– > quickCheck tanApproxProp
– ————————————————————————-
– | Input | |
– | x’ | Floating point input |
– ————————————————————————-
– | Output | True iff tanApprox(x) ~ tan(x) |
– ————————————————————————-
-}
tanApproxProp :: Double -> Bool
tanApproxProp x =
let
— get value of tan for Prelude cos and Student tanApprox
tanRef = tan x
tan_x = Student.tanApprox x
— we’ll allow for this much margin of error
tol = 1e-2
— passes test iff | tan(x) – tanApprox(x) | <= tol in abs (tanRef - tan_x) <= tol ------------------------------------------------------------------------------------------- -- * Run Tests main :: IO () main = hspec $ do describe "sinTaylor" $ do it "should approx. correspond to sin(x) when x-pi/8 <= a <= x+pi/8" $ property $ sinTaylorProp describe "fmod x y = r" $ do it "succeeds if " $ property $ fmodProp describe "sinApprox" $ do it "should correspond to Prelude.sin within a tolerance of 1e-2" $ property $ sinApproxProp describe "cosApprox" $ do it "should correspond to Prelude.cos within a tolerance of 1e-2" $ property $ cosApproxProp describe "tanApprox" $ do it "should correspond to Prelude.tan within a tolerance of 1e-2" $ property $ tanApproxProp