我是初学者,我正在努力解决这个问题code。给定n和List,返回一个新列表,其中包含重复n次列表的所有元素。 以下是我的实施
fn :: Int -> [a] -> [a]
replicate' n x = take n (repeat x)
fn n (x:xs) = case x of [] -> []
(_) -> (replicate' n x) ++ fn n xs
但我收到错误说
Couldn't match type `a' with `[t0]'
`a' is a rigid type variable bound by
the type signature for fn :: Int -> [a] -> [a] at temp.hs:3:1
In the pattern: []
In a case alternative: [] -> []
In the expression:
case x of {
[] -> []
(_) -> (replicate' n x) ++ fn n xs }
我不确定错误在哪里。 注意:我没有尝试monad,任何库。我只使用基本结构 编辑:我现在不担心打印。我想返回逻辑中指定的列表。打印可以在以后进行。
答案 0 :(得分:3)
当您使用模式fn n (x:xs) = ...
时,表示x
是列表中的第一个元素,xs
是列表的其余部分。您的case语句正在检查x
是否为空列表,但模式匹配((x:xs)
)已从列表中提取它。你想要的可能是其中之一(编译器知道它们是相同的,所以你使用的是一个品味问题):
-- Version that uses a pattern match
fn :: Int -> [a] -> [a]
replicate' n x = take n (repeat x)
fn _ [] = []
fn n (x:xs) = (replicate' n x) ++ fn n xs
-- Version that uses a case statement
fn :: Int -> [a] -> [a]
replicate' n x = take n (repeat x)
fn n l = case l of [] -> []
(x:xs) -> (replicate' n x) ++ fn n xs
这个"修复错误",但可能不是你真正想要的:
fn :: Int -> [[a]] -> [[a]]
replicate' n x = take n (repeat x)
fn n (x:xs) = case x of [] -> []
(_) -> (replicate' n x) ++ fn n xs
答案 1 :(得分:3)
Jeremy List的解释直接解决了OP的问题。但是,有时结构化递归可以为问题提供更优雅的解决方案。在这种情况下,例如,这一个衬里完全符合OP的要求:
fn :: Int -> [a] -> [a]
fn n = concat . map (replicate n)
总之, map 提升复制以在列表的值中运行, concat 连接结果列表列表。
我希望这会有所帮助。
答案 2 :(得分:1)
使用do notation
replicate' n xs = do
x <- xs
replicate n x
可以写成
replicate' n xs = xs >>= replicate n
或
replicate' n = (>>= replicate n)
答案 3 :(得分:0)
这是一种具有嵌套列表理解的解决方案。
f n arr =
[ x | x <- arr, _ <- [1..n]]