将元素乘以两个或每个元素乘以(本身 - 1)

时间:2011-11-25 12:52:02

标签: haskell

我需要编写一个函数,它采用正整数列表。如果列表以2开头,则每个元素必须乘以2,在其他情况下,每个整数n写入n-1次。

two :: [Int] -> [Int]

即:

two [2,1] ==> [4,2]

two [3,2,4] ==> [3,3,2,4,4,4]

multiplyEveryoneByTwo :: [Int] -> [Int]
multiplyEveryoneByTwo [] = []
multiplyEveryoneByTwo [x] = [x*2]
multiplyEveryoneByTwo (x:xs) = (x*2) : multiplyEveryoneByTwo xs

replicateEveryone :: [Int] -> [Int]
replicateEveryone [] = []
replicateEveryone [x] = replicate (x-1) x
replicateEveryone (x:xs) = (replicate (x-1) x) ++ replicateEveryone xs

two :: [Int] -> [Int]
two [x] = if x == 2 then [x*2] else replicate (x-1) x
two (x:xs)
    | x == 2 = multiplyEveryoneByTwo (x:xs) 
    | otherwise = replicateEveryone (x:xs)

我现在卡在写:如果列表的第一个元素是2,那么递归地将每个元素乘以2.我尝试使用额外的函数multiplyByTwo,但它不起作用。 else语句是我需要通过(本身 - 1)

复制列表的每个元素

将传递(x:xs)传递给我的辅助函数是正确的方法| x == 2 = multiplyEveryoneByTwo (x:xs) | otherwise = replicateEveryone (x:xs)

2 个答案:

答案 0 :(得分:3)

我建议将你的问题分成两个单独的函数

multiplyEveryoneByTwo :: [Int] -> [Int]
multiplyEveryoneByTwo ...

replicateEveryone :: [Int] -> [Int]
replicateEveryone ...

在对这两个功能进行测试和工作后,您可以创建组合它们的奇怪功能

weirdf [] = ...
weirdf (x:xs)
   | x == 2 = multiplyEveryone (...)
   |otherwise = replicateEveryone (...)

答案 1 :(得分:1)

不完整答案(因为您的问题被标记为[家庭作业]),但要小心您的功能类型。请注意以下类型:

two :: [Int] -> [Int]

但multiplyByTwo可能有类似

的类型
multiplyByTwo :: Int -> Int

因此,编写

时出现输入错误
two (x:xs) = if ... then multiplyByTwo x else ...

if-then-else 表达式的类型必须与两个的返回类型匹配。另外,检查两个分支的类型(然后 else ):它们是否返回相同类型的表达式?如果没有,则还有其他类型错误。