我该如何写这个函数?

时间:2011-07-08 10:12:20

标签: haskell

我想编写一个函数,对于整数列表中的每个元素,如果元素为正,则我们将它乘以100,如果不是,我们将它与另一个整数列表中的每个元素相乘。然后我们将结果打包成一个列表。例如,对于列表[1, 2, -1][100, 200],我们有最终列表[100, 200, -100, -200]

我打算使用列表推导,但我不知道如何在其他列表[100, 200]中工作。到目前为止,我得到了:

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]

代码不起作用,但是可以修复它,还是有更好的构造来解决这个问题?

4 个答案:

答案 0 :(得分:7)

如何使用concatMapconcatMapmap类似,但强制结果类型为列表。然后,将结果列表粘合在一起(展平)。如果您使用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

答案 1 :(得分:4)

您可以使用concatMap等,如FUZxxl建议的那样,或者您可以使用列表理解来执行此操作:

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

同样的事情可以用写法来写:

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

答案 2 :(得分:3)

我会使用concatMap作为@FUZxxl建议,但你也可以用理解来做。关键是您的列表推导首先创建一个嵌套列表,然后使用concat折叠。

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

答案 3 :(得分:0)

我更喜欢这样的事情:

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

但是concatMap解决方案也很不错。他们避免使用重复代码。