Output an element the number of times I want

前端 未结 6 1808
-上瘾入骨i
-上瘾入骨i 2021-01-21 03:11

I have this code:

lado ::  [([Char],Int)] -> [[Char]]
lado xs = [a | (a,b) <- xs]

I need to output this:

> lado [("A         


        
6条回答
  •  太阳男子
    2021-01-21 03:16

    I really like Aplet123's approach, but I think it can be made a bit more efficient. What's wrong with it as is? nonzero is used twice, which means the program will realize its result list rather than fusing it with the consumers of that list. So each time we go through the recursion, we'll allocate three new lists. Can we fix it? Let's start by assuming that the argument has no zeros in it.

    -- Assumes all the Ints are positive
    lado' :: [(a, Int)] -> [a]
    lado' [] = []
    lado' xns = map fst xns ++ rest
      where
        rest = lado' [(x, n - 1) | (x, n) <- xns, n /= 1]
    

    This is already much better. It only allocates two lists each time. But map fst will allocate a bunch of selector thunks to put in the list. We can fix that with another list comprehension:

    -- Assumes all the Ints are positive
    lado' :: [(a, Int)] -> [a]
    lado' [] = []
    lado' xns = start ++ rest
      where
        start = [x | (x, _) <- xns]
        rest = lado' [(x, n - 1) | (x, n) <- xns, n /= 1]
    

    Nice and clean! But what if the original list has zeros? We can filter it up front:

    lado :: [(a, Int)] -> [a]
    lado = lado' . filter (\(_, n) -> n > 0)
    

    There's still one little inefficiency in the case where there are a good number of non-tiny numbers: the representation of the list of pairs. A small improvement:

    data IPair a = IPair a !Int
    

    A bigger improvement would change the implementation of lists:

    data IPList a
      = Cons a !Int (IPList a)
      | Nil
    

    The downside of IPList is that you'd have to ditch list comprehensions.

    I see you're not allowed to use recursion, which is ... quite a silly requirement. Can you see how to work around that with iterate, takeWhile, and concat?

提交回复
热议问题