Changeset 3816

Show
Ignore:
Timestamp:
05/24/05 18:21:26 (4 years ago)
Author:
iblech
svk:copy_cache_prev:
5385
Message:

* map can now take n-ary functions.
* Added a test for n-ary map to map.t.

Files:
2 modified

Legend:

Unmodified
Added
Removed
  • src/Pugs/Prim/List.hs

    r3644 r3816  
    199199op2Map (VList [v@(VRef _)]) sub = op2Map v sub 
    200200op2Map list sub = do 
    201     args <- fromVal list 
    202     vals <- (`mapM` args) $ \x -> do 
    203         evl <- asks envEval 
     201    args  <- fromVal list 
     202    arity <- liftM length $ (fromVal sub >>= return . subParams) 
     203    evl  <- asks envEval 
     204    vals <- mapMn args arity $ \x -> do 
    204205        rv  <- local (\e -> e{ envContext = cxtSlurpyAny }) $ do 
    205             evl (App (Val sub) [Val x] []) 
     206            evl (App (Val sub) (map Val x) []) 
    206207        fromVal rv 
    207     return $ VList $ concat vals 
     208    return $ VList vals 
     209    where 
     210    -- Takes a list, an arity, and a function. 
     211    mapMn  :: [Val] -> Int -> ([Val] -> Eval [Val]) -> Eval [Val] 
     212    mapMn list n f = mapMn' (l2lol n list) f 
     213    -- Takes a LoL and a function and applies the function to the inputlist. 
     214    mapMn' :: [[Val]] -> ([Val] -> Eval [Val]) -> Eval [Val] 
     215    mapMn' (x:xs) f = liftM2 (++) (f x) (mapMn' xs f) 
     216    mapMn' []     _ = return [] 
     217    -- Takes a list and returns a LoL. 
     218    -- Ex.: l2lol 3 [1,2,3,4,5] = [[1,2,3],[4,5,undef]] 
     219    l2lol n list 
     220        | n == 0           = fail "Cannot map() using a nullary function." 
     221        -- If the list has exactly n elements, we've finished our work. 
     222        | length list == n = [list] 
     223        -- If the list is empty, we're done, too. 
     224        | length list == 0 = [] 
     225        -- But if the list contains more elems than we need, we process the 
     226        -- first n ones and the rest separately. 
     227        | length list  > n = (l2lol n $ take n list) ++ (l2lol n $ drop n list) 
     228        -- And if the list contains less elems than we need, we pad with undefs. 
     229        | length list  < n = l2lol n $ list ++ [undef :: Val] 
     230        | otherwise        = fail "Invalid arguments to internal function l2lol passed." 
    208231 
    209232op2Join :: Val -> Val -> Eval Val 
  • t/builtins/lists/map.t

    r3756 r3816  
    1010=cut 
    1111 
    12 plan 48; 
     12plan 52; 
    1313 
    1414my @list = (1 .. 5); 
     
    9797    is(%result<5>, 10, 'got the value we expected'); 
    9898} 
     99 
     100# map with n-ary functions 
     101{ 
     102  is ~(1,2,3,4).map:{ $^a + $^b             }, "3 7", "map() works with 2-ary functions"; 
     103  is ~(1,2,3,4).map:{ $^a + $^b + $^c       }, "6 4", "map() works with 3-ary functions"; 
     104  is ~(1,2,3,4).map:{ $^a + $^b + $^c + $^d }, "10",  "map() works with 4-ary functions"; 
     105  is ~(1,2,3,4).map:{ $^a+$^b+$^c+$^d+$^e   }, "10",  "map() works with 5-ary functions"; 
     106}