user618815
user618815

Reputation:

How do I write this function?

I want to write a function that for every element in a list of integers, if the element is positive then we multiply it by 100, and if it is not we multiply it with each element in another list of integers. Then we pack up the result into a list. For example, for list [1, 2, -1] and the [100, 200], we have the final list [100, 200, -100, -200]

I meant to use list comprehensions, but I don't know how to work in the other list, [100, 200]. So far I got:

toyFunc :: [Int] -> [Int]
toyFunc lst_int =
    [let res =
             if elem > 0 then elem *100 else ------> how to write this else part?
     in res | elem <- lst_int]

The code doesn't work, but is it possible to fix it, or is there a better construct for this problem?

Upvotes: 2

Views: 195

Answers (4)

eternalmatt
eternalmatt

Reputation: 3564

I would prefer something like this:

toy :: (Integral a) => [a] -> [a] -> [a]
toy (x:xs) otherList
   | x >=0     = (100*x)            : toy xs otherList
   | otherwise = map (*x) otherList : toy xs otherList

But concatMap solutions are pretty good too. They avoid repetetive code.

Upvotes: 0

Rotsor
Rotsor

Reputation: 13793

You can use concatMap etc., like FUZxxl suggested, or you can do it with a list comprehension:

toyFunc :: [Int] -> [Int] -> [Int]
toyFunc list replacement =
     [y | 
      x <- list, 
      y <- if x > 0 
         then [x * 100]
         else [x * r | r <- replacement]
     ]

The same thing can be written with do-notation:

toyFunc list replacement = do
  x <- list
  if x > 0
      then return (x * 100)
      else do
        r <- replacement
        return (x * r)

Upvotes: 4

John L
John L

Reputation: 28097

I would use concatMap as @FUZxxl suggests, but you can do it with comprehensions too. The key is that your list comprehension first creates a nested list, which is then collapsed with concat.

toyFunc :: [Int] -> [Int] -> [Int]
toyFunc lstInt refList = concat
    [if elem > 0 then [elem *100] else map (* elem) refList
     | elem <- lstInt]

Upvotes: 3

fuz
fuz

Reputation: 93172

How about using concatMap? concatMap is like map, but forces the result type to be a list. Then, the result lists are glued together (flattend). It is easy if you use concatMap:

toyFunc :: [Int] -> [Int] -> [Int] -- Recall, that you have two lists
toyFunc list replacement = concatMap mapper list where
  mapper x | x > 0     = [x * 100]
           | otherwise = map (*x) replacement

Upvotes: 7

Related Questions