打印列表中的每个值" n"时

时间:2015-07-06 06:39:57

标签: haskell

我是初学者,我正在努力解决这个问题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,任何库。我只使用基本结构 编辑:我现在不担心打印。我想返回逻辑中指定的列表。打印可以在以后进行。

4 个答案:

答案 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]]