@@ -144,8 +144,8 @@ A structure with class
144144----------------------------------------------------------------------
145145
146146Now that we've defined the basic structure of our language, we can
147- instantiate some useful classes. There are two in particular we care
148- for: `Show` and `Arbitrary`.
147+ instantiate some useful classes. There are three in particular we care
148+ for: `Show`, `Num`, and `Arbitrary`.
149149
150150Try modifying `FunExpr` to derive `Show`, so that our expressions can be printed.
151151
@@ -197,17 +197,33 @@ expressions in a much more human friendly way!
197197
198198Still a bit noisy with all the parentheses, but much better!
199199
200- Another class we can instance for our `FunExpr` is
201- `Arbitrary`. This class is associated with the testing library
202- *QuickCheck*, and describes how to generate arbitrary values of a type
203- for use when testing logical properties with `quickCheck`. For
204- example, a property function could be formulated that states that the
205- `:*` constructor of `FunExpr` is associative.
200+ Another class we can instantiate for our `FunExpr` is `Num`. This
201+ class allows us to make use of the native Haskell functions and
202+ operators for numeric operations, instead of writing our own
203+ constructors. This sometimes improves the readability of the code.
204+
205+ > instance Num FunExpr where
206+ > negate e = Const 0 :- e
207+ > (+) = (:+)
208+ > (*) = (:*)
209+ > fromInteger = Const . fromInteger
210+ > abs = undefined
211+ > signum = undefined
212+
213+ Third but not least, we'll instantiate `Arbitrary`. This class is
214+ associated with the testing library *QuickCheck*, and describes how to
215+ generate arbitrary values of a type for use when testing logical
216+ properties with `quickCheck`. For example, a property function could
217+ be formulated that states that the `:*` constructor of `FunExpr` is
218+ associative.
206219
207220The implementation itself is not very interesting. We generate a
208221function expression that tends to contain mostly elementary functions,
209222arithmetic operations, and a generous dose of constants; with a light
210- sprinkle of differences, derivatives, and integrals.
223+ sprinkle of differences. We won't include derivatives as all
224+ elementary functions have elementary derivatives anyways, and
225+ integrals may cause cause approximation errors if we have to
226+ numerically compute them at evaluation.
211227
212228> instance Arbitrary FunExpr where
213229> arbitrary =
@@ -223,10 +239,9 @@ generated expressions in complexity.
223239> , (10 , return Id )
224240> , (20 , fmap Const arbitrary)
225241> , (10 , genBinaryApp (:.) )
226- > , (5 , genBinaryApp Delta )
227- > , (5 , fmap D arbitrary)
228- > , (5 , fmap I arbitrary) ]
242+ > , (5 , genBinaryApp Delta ) ]
229243> where genElementary = elements [Exp , Log , Sin , Cos , Asin , Acos ]
230244> genBinaryApp op = fmap (\ (f, g) -> f `op` g) arbitrary
231245> genBinaryOperation = elements [(:+) , (:-) , (:*) , (:/) , (:^) ]
232246> >>= genBinaryApp
247+
0 commit comments