Haskell “打印列表中的每个值”;";时代
我是一个初学者,我正在努力解决这个问题。给定n和一个列表,返回一个新列表,其中包含重复n次的列表的所有元素。 下面是我的实现Haskell “打印列表中的每个值”;";时代,haskell,Haskell,我是一个初学者,我正在努力解决这个问题。给定n和一个列表,返回一个新列表,其中包含重复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 matc
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,任何库。我只使用基本的构造
编辑:我现在不担心打印。我想返回逻辑中指定的列表。以后可以进行打印。当您使用模式
fn(x:xs)=……
时,这意味着x
是列表中的第一个元素,xs
是列表的其余部分。您的case语句正在检查x
是否为空列表,但模式匹配((x: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
Jeremy List的解释直接解决了OP的问题。然而,有时结构化递归为问题提供了更优雅的解决方案。例如,在这种情况下,这一行程序完全符合OP的要求:
fn :: Int -> [a] -> [a]
fn n = concat . map (replicate n)
总之,map提升replicate以在列表的值中进行操作,concat连接生成的列表列表
我希望这有帮助 使用do表示法
replicate' n xs = do
x <- xs
replicate n x
或
使用
concatMap
这里会有一点风格上的改进,IMHO。@Luiscasilas完全正确,concatMap会更好一点!无论如何,我认为一个独立的concat和map的组合会更容易理解,因为OP说基本的构造是首选的。答案很好!揭示列表是如何单子的
replicate' n xs = do
x <- xs
replicate n x
replicate' n xs = xs >>= replicate n
replicate' n = (>>= replicate n)