Changeset 3501

Show
Ignore:
Timestamp:
05/20/05 13:59:49 (4 years ago)
Author:
iblech
svk:copy_cache_prev:
5078
Message:

uniq() implemented (with inplace syntax too), tests pass :)

Files:
3 modified

Legend:

Unmodified
Added
Removed
  • src/Pugs/Prim.hs

    r3495 r3501  
    462462op1 "min"   = op1Min 
    463463op1 "max"   = op1Max 
     464op1 "uniq"  = op1Uniq 
    464465op1 "chr"   = op1Cast (VStr . (:[]) . chr) 
    465466op1 "ord"   = op1Cast $ \str -> if null str then undef else (castV . ord . head) str 
     
    10841085\\n   Scalar    pre     min     (List)\ 
    10851086\\n   Scalar    pre     max     (List)\ 
     1087\\n   List      pre     uniq    (List)\ 
    10861088\\n   Str       pre     join    (Array: Str)\ 
    10871089\\n   Str       pre     join    (Str, List)\ 
  • src/Pugs/Prim/List.hs

    r3495 r3501  
    11module Pugs.Prim.List ( 
    22    op0Zip, op1Pick, op1Sum, 
    3     op1Min, op1Max, 
     3    op1Min, op1Max, op1Uniq, 
    44    op2FoldL, op2Fold, op2Grep, op2Map, op2Join, 
    55    sortByM, 
     
    102102        return $ if min_or_max (cmp > (0::VInt)) then a else b 
    103103 
     104op1Uniq v = do 
     105    -- We want to have a real Haskell list 
     106    args    <- fromVal v 
     107    -- Extract our comparator sub, or Nothing if none was specified 
     108    (valList, cmp) <- case args of 
     109        (v:vs) -> do 
     110            ifValTypeIsa v "Code" 
     111                (return (vs, Just v)) 
     112                (ifValTypeIsa (last args) "Code" 
     113                    (return (init args, Just $ last args)) 
     114                    (return (args, Nothing))) 
     115        _  -> return (args, Nothing) 
     116    -- After this parameter unpacking, we begin doing the real work. 
     117    op1Uniq' cmp valList 
     118    where 
     119    op1Uniq' :: (Maybe Val) -> [Val] -> Eval Val 
     120    -- If the user didn't specify an own comparasion sub, we can simply use 
     121    -- Haskell's nub. 
     122    op1Uniq' Nothing valList = return . VList $ nub valList 
     123    -- Else, we have to write our own nubByM and use that. 
     124    op1Uniq' (Just subVal) valList = do 
     125        sub <- fromVal subVal 
     126        evl <- asks envEval 
     127        -- Here we execute the user's sub 
     128        result <- nubByM (\a b -> do 
     129            rv  <- local (\e -> e{ envContext = cxtItem "Bool" }) $ do 
     130                evl (App (Val sub) [Val a, Val b] []) 
     131            -- The sub returns either true or false. 
     132            bool <- fromVal rv 
     133            return . VBool $ bool) valList 
     134        return . VList $ result 
     135    -- This is the same as nubBy, only lifted into the Eval monad 
     136    nubByM :: (Val -> Val -> Eval Val) -> [Val] -> Eval [Val] 
     137    nubByM eq l = nubByM' l [] 
     138      where 
     139        nubByM' [] _      = return [] 
     140        nubByM' (y:ys) xs = do 
     141            -- elemByM returns a Val, but we need a VBool, so we have to use fromVal. 
     142            cond <- fromVal =<< elemByM eq y xs 
     143            if cond then nubByM' ys xs else do 
     144                result <- nubByM' ys (y:xs) 
     145                return (y:result) 
     146        elemByM :: (Val -> Val -> Eval Val) -> Val -> [Val] -> Eval Val 
     147        elemByM _  _ []     = return . VBool $ False 
     148        elemByM eq y (x:xs) = do 
     149            cond <- fromVal =<< eq x y 
     150            -- Same here (we need a VBool, not a Var). 
     151            if cond then return . VBool $ cond else elemByM eq y xs 
     152 
    104153op2FoldL :: Val -> Val -> Eval Val 
    105154op2FoldL sub@(VCode _) list = op2FoldL list sub 
  • t/builtins/lists/uniq.t

    r3500 r3501  
    2020  my @array = <a b b c d e b b b b f b>; 
    2121  is ~@array, "a b b c d e b b b b f b",  "basic sanity"; 
    22   is eval('~@array.uniq'), "a b c d e f", "method form of uniq works", :todo; 
    23   is eval('~uniq @array'), "a b c d e f", "subroutine form of uniq works", :todo; 
    24   ok eval('@array.=uniq'),                "inplace form of uniq works (1)", :todo; 
    25   is      ~@array,         "a b c d e f", "inplace form of uniq works (2)", :todo; 
     22  is eval('~@array.uniq'), "a b c d e f", "method form of uniq works"; 
     23  is eval('~uniq @array'), "a b c d e f", "subroutine form of uniq works"; 
     24  ok eval('@array.=uniq'),                "inplace form of uniq works (1)"; 
     25  is      ~@array,         "a b c d e f", "inplace form of uniq works (2)"; 
    2626} 
    2727 
     
    3030  my @array = <a b A c b d>; 
    3131  # Semantics w/o junctions 
    32   is eval('~@array.uniq:{ lc $^a eq lc $^b }'), "a b c d", "method form of uniq with own comparator works", :todo; 
    33   is eval('~uniq { lc $^a eq lc $^b } @array'), "a b c d", "subroutine form of uniq with own comparator works", :todo; 
     32  is eval('~@array.uniq:{ lc $^a eq lc $^b }'), "a b c d", "method form of uniq with own comparator works"; 
     33  is eval('~uniq { lc $^a eq lc $^b } @array'), "a b c d", "subroutine form of uniq with own comparator works"; 
    3434 
    3535  # Semantics w/ junctions