开发者

How do you solve this Haskell problem using a fold map and take? [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this qu开发者_C百科estion more broadly applicable, visit the help center. Closed 10 years ago.

Define a function replicate which given a list of numbers returns a list with each number duplicated its value. Use a fold, map, and take

..> replicate [5,1,3,2,8,1,2]

output: [5,5,5,5,5,1,3,3,3,2,2,8,8,8,8,8,8,8,8,1,2,2]

I've figure this out using List comprehension and recursion:

replicate2 [] = []
replicate2 (n:nn) = take n(repeat n) ++ replicate2 nn

but how would you use fold and map to do this? so far I have: replicate n = map (foldl1 (take n(repeat n)) n) n which is obviously wrong, but I think I am close..

so any help would be nice, THANKS!


The key in Haskell is always follow the types:

foldr  :: (a -> b -> b) -> b -> [a] -> b
foldr1 :: (a -> a -> a)      -> [a] -> a
map    :: (a -> b)           -> [a] -> [b]
take   :: Int                -> [a] -> [a]

I've added some spaces here to make it a bit more clear how these three functions compare. Remember when you look at these that a type variable, a or b, can match any type, including things like String, or [Float], or even [(String,[Int])]. For example, in the expression:

foldr (\a b -> product a + b) (0::Int) [[1,2,4],[5,2],[0,3,6]]

foldr is being used as type ([Int] -> Int -> Int) -> Int -> [[Int]] -> Int. That is a has matched [Int] and b has matched Int.

Now: Think about at the "outermost" level what your expression has to do. Which of these functions fits that form?

Can you cast your problem into an outer expression that has one of these forms and an "inner" problem?


You've got your function application order mixed up. Think about what you need to be able to do:

  1. Turn a number n into a list of n copies of itself
  2. Apply operation #1 on every number in a list
  3. Concatenate all the lists you got from #2 together.

You know how to do 1: take n $ repeat n
Of 2 and 3, which is a map and which is a fold?

Step 2. is a map - you're mapping ("transforming") every item in the list, into a list.
Step 3. is a fold, since you're aggregating ("flattening") a bunch of list elements into one.


replicate xs = foldl (++) [] (map (\n->take n $ repeat n) xs) 

The idea is map on every element of a list which just repeats an element x , x number of times. Then fold on the list to concatenate it. Suppose the list is [5,1,2]

So (map (\n->take n $ repeat n) xs) is [[5,5,5,5,5],[1],[2,2]] and then you just have to concatenate the inner lists.


replicate2 lst = concatMap(\x ->  (take x) (repeat x)) lst
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜