(* This is a filter: it tests values of type 'a. * A filter contains two functions: forbid and f (see the type definition). * * We say that a filter: * - forbids a value x if forbid x returns a non-empty string. * - accepts a value x if f x returns true * - rejects a value x if f x returns false * * The forbid test is done first: if a value is forbidden, it cannot be accepted or rejected. * * Example with an int filter : * if forbid (-1) returns "a negative number, this is insane!", this means that -1 is a forbidden value. * if forbid 12 returns "", this means that 12 is not forbidden. * * if f 12 returns true, this means that 12 is accepted. * if f 17 returns false, this means that 17 is rejected (assuming 17 is not forbidden either: forbid 17 returns "") *) type 'a filter = { forbid: ('a -> string) ; f: ('a -> bool) } (* When a filter is applied to a value, it returns one of these. *) type result = Forbid of string | Accept | Reject (* Forbid contains the message returned by the forbid function. * It cannot be empty. *) (* In some tests, we use some predefined filters : * * filter_even : int filter, forbids : negative numbers, accepts : even numbers (2,4,6,8, ...) * filter_odd : int filter, forbids : 0, accepts : odd numbers (1,3,-5,-7,...) * * filter_pair : (int*int) filter, forbids pairs (a,b) when a is a negative number, accepts pairs with equal values, e.g. (4,4) * *)