[Removed all uses of implicit parameters. Nils Anders Danielsson **20060406082913 + I think they are rather ugly, and I didn't use the functionality provided by them anyway. + This implies that the library interface has changed in a non-backwards-compatible way. ] { hunk ./Header 57 - [@> let ?approxDepth = Just 5; ?timeOutLimit = Just 2 in (reverse [1..\], [1..\]) ==? (bottom :: [Int\], [1..\] :: [Int\])@] @True@ + [@> let tweak = Tweak { approxDepth = Just 5, timeOutLimit = Just 2 }@] hunk ./Header 59 - [@> let ?approxDepth = Nothing; ?timeOutLimit = Just 2 in (reverse [1..\], True) \\\/? ([\] :: [Int\], bottom)@] @Just ([],True)@ + [@> semanticEq tweak (reverse [1..\], [1..\]) (bottom :: [Int\], [1..\] :: [Int\])@] @True@ hunk ./Header 61 -That can of course be dangerous: + [@> let tweak = noTweak { timeOutLimit = Just 2 }@] hunk ./Header 63 - [@> let ?approxDepth = Nothing; ?timeOutLimit = Just 0 in reverse [1..100000000\] ==? (bottom :: [Integer\])@] @True@ + [@> semanticJoin tweak (reverse [1..\], True) ([\] :: [Int\], bottom)@] @Just ([],True)@ + +This can of course be dangerous: + + [@> let tweak = noTweak { timeOutLimit = Just 0 }@] + + [@> semanticEq tweak (reverse [1..100000000\]) (bottom :: [Integer\])@] @True@ hunk ./Header 94 -exceptions, though. Implicit parameters are also used for some parts -of the code, but that can be avoided by changing the interface. +exceptions, though. hunk ./Test/ChasingBottoms/IsBottom.hs 1 -{-# OPTIONS -fimplicit-params #-} - hunk ./Test/ChasingBottoms/IsBottom.hs 8 --- Portability : non-portable (exceptions, implicit parameters) +-- Portability : non-portable (exceptions) hunk ./Test/ChasingBottoms/IsBottom.hs 51 -isBottom = let ?timeOutLimit = Nothing in isBottomTimeOut +isBottom = isBottomTimeOut Nothing hunk ./Test/ChasingBottoms/IsBottom.hs 64 --- | 'isBottomTimeOut' works like 'isBottom', but if @?timeOutLimit@ --- is @'Just' lim@, then computations taking more than @lim@ seconds are --- also considered to be equal to bottom. Note that this is a very --- crude approximation of what a bottom is. Also note that this --- \"function\" may return different answers upon different +-- | @'isBottomTimeOut' timeOutLimit@ works like 'isBottom', but if +-- @timeOutLimit@ is @'Just' lim@, then computations taking more than +-- @lim@ seconds are also considered to be equal to bottom. Note that +-- this is a very crude approximation of what a bottom is. Also note +-- that this \"function\" may return different answers upon different hunk ./Test/ChasingBottoms/IsBottom.hs 74 -isBottomTimeOut :: (?timeOutLimit :: Maybe Int) => a -> Bool -isBottomTimeOut f = unsafePerformIO $ +isBottomTimeOut :: Maybe Int -> a -> Bool +isBottomTimeOut timeOutLimit f = unsafePerformIO $ hunk ./Test/ChasingBottoms/IsBottom.hs 94 - maybeTimeOut io = case ?timeOutLimit of + maybeTimeOut io = case timeOutLimit of hunk ./Test/ChasingBottoms/SemanticOrd/Tests.hs 4 --- implicit arguments are currently not tested. +-- tweaks are currently not tested. hunk ./Test/ChasingBottoms/SemanticOrd/Tests.hs 48 - case semanticCompare x y of + case semanticCompare noTweak x y of hunk ./Test/ChasingBottoms/SemanticOrd.hs 21 --- Some functions take the implicit parameters @?approxDepth@ and --- @?timeOutLimit@. They have the following meaning: --- --- [@?approxDepth@] If equal to @'Just' n@, an @'approxAll' n@ is --- performed on all arguments before doing whatever the function is --- supposed to be doing. --- --- [@?timeOutLimit@] If equal to @'Just' n@, then all computations --- that take more than @n@ seconds to complete are considered to be --- equal to 'bottom'. This functionality is implemented using --- 'isBottomTimeOut'. --- --- Note that the use of implicit parameters here is more experimental --- than the rest of the library, and hence more likely to be removed --- in future versions. --- hunk ./Test/ChasingBottoms/SemanticOrd.hs 26 - ( SemanticEq(..) + ( Tweak(..) + , noTweak + , SemanticEq(..) hunk ./Test/ChasingBottoms/SemanticOrd.hs 40 -infix 4 =?, >?, /=? -infix 5 \/!, \/? -infixl 5 /\!, /\? +infix 5 \/! +infixl 5 /\! + +-- | The behaviour of some of the functions below can be tweaked. + +data Tweak = Tweak + { approxDepth :: Maybe Nat + -- ^ If equal to @'Just' n@, an @'approxAll' n@ is performed on + -- all arguments before doing whatever the function is supposed to + -- be doing. + , timeOutLimit :: Maybe Int + -- ^ If equal to @'Just' n@, then all computations that take more + -- than @n@ seconds to complete are considered to be equal to + -- 'bottom'. This functionality is implemented using + -- 'isBottomTimeOut'. + } + deriving (Eq, Ord, Show) + +-- | No tweak (both fields are 'Nothing'). + +noTweak :: Tweak +noTweak = Tweak + { approxDepth = Nothing + , timeOutLimit = Nothing + } hunk ./Test/ChasingBottoms/SemanticOrd.hs 76 - (==?), (/=?) :: ( ?approxDepth :: Maybe Nat - , ?timeOutLimit :: Maybe Int - ) => a -> a -> Bool - - (/=?) = \x y -> not (x ==? y) + semanticEq :: Tweak -> a -> a -> Bool hunk ./Test/ChasingBottoms/SemanticOrd.hs 79 - - (==!) = bindImpl (==?) + (==!) = semanticEq noTweak hunk ./Test/ChasingBottoms/SemanticOrd.hs 86 - (=?), (>?) :: - ( ?approxDepth :: Maybe Nat - , ?timeOutLimit :: Maybe Int - ) => a -> a -> Bool hunk ./Test/ChasingBottoms/SemanticOrd.hs 87 - semanticCompare :: a -> a -> Maybe Ordering - semanticCompare' :: ( ?approxDepth :: Maybe Nat - , ?timeOutLimit :: Maybe Int - ) => a -> a -> Maybe Ordering - -- ^ @'semanticCompare' x y@ returns 'Nothing' if @x@ and @y@ are + semanticCompare :: Tweak -> a -> a -> Maybe Ordering + -- ^ @'semanticCompare' tweak x y@ returns 'Nothing' if @x@ and @y@ are hunk ./Test/ChasingBottoms/SemanticOrd.hs 94 - (\/?) :: ( ?approxDepth :: Maybe Nat - , ?timeOutLimit :: Maybe Int - ) => a -> a -> Maybe a - (/\?) :: ( ?approxDepth :: Maybe Nat - , ?timeOutLimit :: Maybe Int - ) => a -> a -> a + semanticJoin :: Tweak -> a -> a -> Maybe a + semanticMeet :: Tweak -> a -> a -> a hunk ./Test/ChasingBottoms/SemanticOrd.hs 108 - (>=?) = flip (<=?) - ( x <=? y && x /=? y - (>?) = \x y -> x >=? y && x /=? y - - (<=!) = bindImpl (<=?) - - semanticCompare = bindImpl semanticCompare' - - semanticCompare' x y | x ? y = Just Prelude.GT - | otherwise = Nothing - - x <=? y = case semanticCompare' x y of + x <=! y = case semanticCompare noTweak x y of hunk ./Test/ChasingBottoms/SemanticOrd.hs 113 - (\/!) = bindImpl (\/?) - - (/\!) = bindImpl (/\?) + (\/!) = semanticJoin noTweak + (/\!) = semanticMeet noTweak hunk ./Test/ChasingBottoms/SemanticOrd.hs 117 - (==?) = liftAppr (==??) + semanticEq tweak = liftAppr tweak semanticEq' hunk ./Test/ChasingBottoms/SemanticOrd.hs 120 - (<=?) = liftAppr (<=??) - (/\?) = liftAppr (/\??) - (\/?) = liftAppr (\/??) - -liftAppr op x y = appr x `op` appr y - where appr = maybe id approxAll ?approxDepth - --- Non-trivial type... + semanticCompare tweak = liftAppr tweak semanticCompare' + where + semanticCompare' tweak x y = + case ( semanticEq' tweak x y + , semanticLE' tweak x y + , semanticLE' tweak y x ) of + (True, _, _) -> Just EQ + (_, True, _) -> Just LT + (_, _, True) -> Just Prelude.GT + (_, _, _) -> Nothing + semanticJoin tweak = liftAppr tweak semanticJoin' + semanticMeet tweak = liftAppr tweak semanticMeet' hunk ./Test/ChasingBottoms/SemanticOrd.hs 133 -bindImpl :: - (forall . (?approxDepth :: Maybe Nat, ?timeOutLimit :: Maybe Int) => a) -> a -bindImpl f = let ?approxDepth = Nothing - ?timeOutLimit = Nothing - in f +liftAppr :: (Data a, Data b) => Tweak -> (Tweak -> a -> a -> b) -> a -> a -> b +liftAppr tweak op x y = op tweak (appr x) (appr y) + where appr = maybe id approxAll (approxDepth tweak) hunk ./Test/ChasingBottoms/SemanticOrd.hs 139 -type Rel = (?timeOutLimit :: Maybe Int, Data a, Data b) => a -> b -> Bool +type Rel' = (Data a, Data b) => Tweak -> a -> b -> Bool +type Rel = (Data a, Data b) => a -> b -> Bool hunk ./Test/ChasingBottoms/SemanticOrd.hs 142 -(==??), (<=??) :: Rel +semanticEq', semanticLE' :: Rel' hunk ./Test/ChasingBottoms/SemanticOrd.hs 144 -a ==?? b = case (isBottomTimeOut a, isBottomTimeOut b) of +semanticEq' tweak a b = case ( isBottomTimeOut (timeOutLimit tweak) a + , isBottomTimeOut (timeOutLimit tweak) b ) of hunk ./Test/ChasingBottoms/SemanticOrd.hs 147 - (False, False) -> allOK (==??) a b + (False, False) -> allOK (semanticEq' tweak) a b hunk ./Test/ChasingBottoms/SemanticOrd.hs 150 -a <=?? b = case (isBottomTimeOut a, isBottomTimeOut b) of +semanticLE' tweak a b = case ( isBottomTimeOut (timeOutLimit tweak) a + , isBottomTimeOut (timeOutLimit tweak) b ) of hunk ./Test/ChasingBottoms/SemanticOrd.hs 153 - (False, False) -> allOK (<=??) a b + (False, False) -> allOK (semanticLE' tweak) a b hunk ./Test/ChasingBottoms/SemanticOrd.hs 179 -(/\??) :: (?timeOutLimit :: Maybe Int, Data a, Data b) => a -> b -> b -a /\?? (b :: b) = - if isBottomTimeOut a || isBottomTimeOut b then +semanticMeet' :: (Data a, Data b) => Tweak -> a -> b -> b +semanticMeet' tweak a (b :: b) = + if isBottomTimeOut (timeOutLimit tweak) a || + isBottomTimeOut (timeOutLimit tweak) b then hunk ./Test/ChasingBottoms/SemanticOrd.hs 189 - gzipWithT (/\??) a b + gzipWithT (semanticMeet' tweak) a b hunk ./Test/ChasingBottoms/SemanticOrd.hs 191 -(\/??) :: (?timeOutLimit :: Maybe Int, Data a, Data b) => a -> b -> Maybe b -a \/?? (b :: b) = - case (isBottomTimeOut a, isBottomTimeOut b) of +semanticJoin' :: (Data a, Data b) => Tweak -> a -> b -> Maybe b +semanticJoin' tweak a (b :: b) = + case ( isBottomTimeOut (timeOutLimit tweak) a + , isBottomTimeOut (timeOutLimit tweak) b ) of hunk ./Test/ChasingBottoms/SemanticOrd.hs 202 - | otherwise -> gzipWithM (\/??) a b + | otherwise -> gzipWithM (semanticJoin' tweak) a b }