我有以下功能:
replace :: a -> Int -> [a] -> [a]
replace elem 0 x:xs = elem : xs
replace elem i x:xs = x ++ replace elem (i - 1) xs
GHCi告诉我,我在类型错误中有一个非法文字,特别是第一个定义中的文字0。现在,我知道如果我试图替换列表中的任意项目,我不应该使用列表数据结构。这很好,因为我计划在我能够得到我想要的工作时立即重构我的程序。
就编译器的抱怨而言,我并不确定为什么Haskell认为我试图在这里定义类型。对此有任何帮助将非常感激。
答案 0 :(得分:3)
正如@ user2407038所提到的,您的代码存在两个直接问题 - 您正在使用(++)
代替(:)
- 您可以这样解决:
replace :: a -> Int -> [a] -> [a]
replace elem 0 (x:xs) = elem : xs
replace elem i (x:xs) = x : replace elem (i - 1) xs
但这样做仍然只会给你一个部分定义,因为你不匹配a
的空列表(GHC会告诉你一个警告) - 解决这个问题只需添加缺少的案例:
replace :: a -> Int -> [a] -> [a]
replace _ _ [] = []
replace elem 0 (x:xs) = elem : xs
replace elem i (x:xs) = x : replace elem (i - 1) xs
最后你可以删除一些未使用的绑定(变量)并重命名elem
(已在前奏中定义)以使GHC更加开心(-Wall):
replace :: a -> Int -> [a] -> [a]
replace _ _ [] = []
replace el 0 (_:xs) = el : xs
replace el i (x:xs) = x : replace el (i - 1) xs
答案 1 :(得分:0)
我通过删除一个空的缩进空间解决了这个问题。我相信编译器认为这段代码是以前(无关)表达式的一部分。另外,我接受了评论者的建议,并将x ++
替换为x :