Changeset 3495
- Timestamp:
- 05/20/05 12:01:14 (4 years ago)
- svk:copy_cache_prev:
- 5078
- Files:
-
- 3 modified
-
src/Pugs/Prim.hs (modified) (2 diffs)
-
src/Pugs/Prim/List.hs (modified) (3 diffs)
-
t/builtins/lists/minmax.t (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Pugs/Prim.hs
r3494 r3495 460 460 op1 "pick" = op1Pick 461 461 op1 "sum" = op1Sum 462 op1 "min" = op1Min 463 op1 "max" = op1Max 462 464 op1 "chr" = op1Cast (VStr . (:[]) . chr) 463 465 op1 "ord" = op1Cast $ \str -> if null str then undef else (castV . ord . head) str … … 1079 1081 \\n Scalar pre pop (rw!Array)\ 1080 1082 \\n Scalar pre shift (rw!Array)\ 1081 \\n Num pre sum (List)\ 1083 \\n Scalar pre sum (List)\ 1084 \\n Scalar pre min (List)\ 1085 \\n Scalar pre max (List)\ 1082 1086 \\n Str pre join (Array: Str)\ 1083 1087 \\n Str pre join (Str, List)\ -
src/Pugs/Prim/List.hs
r3477 r3495 1 1 module Pugs.Prim.List ( 2 2 op0Zip, op1Pick, op1Sum, 3 op1Min, op1Max, 3 4 op2FoldL, op2Fold, op2Grep, op2Map, op2Join, 4 5 sortByM, … … 10 11 11 12 import Pugs.Prim.Numeric 13 import Pugs.Prim.Lifts 12 14 13 15 op0Zip :: [Val] -> Eval Val … … 47 49 vals <- fromVal list 48 50 foldM (op2Numeric (+)) undef vals 51 52 op1Min :: Val -> Eval Val 53 op1Min v = op1MinMax (== False) v 54 55 op1Max :: Val -> Eval Val 56 op1Max v = op1MinMax (== True) v 57 58 -- min_or_max is a function which negates truth/falsehood. 59 -- This is necessary as op1MinMax should cope with min() as well as max(). 60 op1MinMax :: (Bool -> Bool) -> Val -> Eval Val 61 op1MinMax min_or_max v = do 62 -- We want to have a real Haskell list 63 args <- fromVal v 64 -- Extract our comparator sub, or Nothing if none was specified 65 (valList, cmp) <- case args of 66 (v:vs) -> do 67 ifValTypeIsa v "Code" 68 (return (vs, Just v)) 69 (ifValTypeIsa (last args) "Code" 70 (return (init args, Just $ last args)) 71 (return (args, Nothing))) 72 _ -> return (args, Nothing) 73 -- Now let our helper function do the rest 74 op1MinMax' min_or_max cmp valList 75 where 76 op1MinMax' :: (Bool -> Bool) -> (Maybe Val) -> [Val] -> Eval Val 77 -- The min or max of an empty list is undef. 78 op1MinMax' _ _ [] = return undef 79 -- We have to supply our own comparator... 80 op1MinMax' _ Nothing valList = foldM default_compare (head valList) valList 81 -- or use the one of the user 82 op1MinMax' min_or_max (Just subVal) valList = do 83 sub <- fromVal subVal 84 evl <- asks envEval 85 -- Here we execute the user's sub 86 foldM (\a b -> do 87 rv <- local (\e -> e{ envContext = cxtItem "Int" }) $ do 88 evl (App (Val sub) [Val a, Val b] []) 89 int <- fromVal rv 90 -- If the return value from the sub was 91 -- -1 ==> a < b 92 -- 0 ==> a == b 93 -- +1 ==> a > b 94 -- We call min_or_max so we can work for both min() and max(). 95 return $ if min_or_max (int > (0::VInt)) then a else b) (head valList) valList 96 -- This is the default comparision function, which will be used if the user 97 -- hasn't specified a own comparision function. 98 default_compare a b = do 99 a' <- vCastRat a 100 b' <- vCastRat b 101 let cmp = if a' < b' then (-1) else if a' == b' then 0 else 1 102 return $ if min_or_max (cmp > (0::VInt)) then a else b 49 103 50 104 op2FoldL :: Val -> Val -> Eval Val -
t/builtins/lists/minmax.t
r2406 r3495 4 4 use v6; 5 5 6 plan 6;6 plan 8; 7 7 8 8 =head1 DESCRIPTION … … 18 18 19 19 # Tests for C<min>: 20 eval_is '@array.min', -9, "basic method form of min works", :todo; 21 eval_is 'min @array', -9, "basic subroutine form of min works", :todo; 22 eval_is '@array.min:{ abs $^a <=> abs $^b }', 0, 23 "method form of min taking a comparision block works", :todo; 20 is @array.min, -9, "basic method form of min works"; 21 is min(@array), -9, "basic subroutine form of min works"; 22 is @array.min:{ abs $^a <=> abs $^b }, 0, 23 "method form of min taking a comparision block works"; 24 is min({ abs $^a <=> abs $^b }, @array), 0, 25 "subroutine form of min taking a comparision block works"; 24 26 25 27 # Tests for C<max>: 26 eval_is '@array.max', 7, "basic method form of max works", :todo; 27 eval_is 'max @array', 7, "basic subroutine form of max works", :todo; 28 eval_is '@array.max:{ abs $^a <=> abs $^b }', 9, 29 "method form of max taking a comparision block works", :todo; 28 is @array.max, 7, "basic method form of max works"; 29 is max(@array), 7, "basic subroutine form of max works"; 30 is @array.max:{ abs $^a <=> abs $^b }, -9, 31 "method form of max taking a comparision block works"; 32 is max({ abs $^a <=> abs $^b }, @array), -9, 33 "subroutine form of max taking a comparision block works";
