Haskell列表连接推断类型

Chr*_*nks 1 haskell list inferred-type

尝试使用新元素替换给定点的列表中的元素,然后返回该元素.

 setelt :: Int -> [a] -> a -> [a]
 setelt x (yf:(y:yl)) z
   | x == (length yf) = (yf:(z:yl))
Run Code Online (Sandbox Code Playgroud)

结果出现此错误:

Inferred type is not general enough
Expression    : setelt
Expected type : Int -> [a] -> a -> [a]
Inferred type : Int -> [[a]] -> [a] -> [[a]]
Run Code Online (Sandbox Code Playgroud)

似乎没有连接的问题yf:y:yl所以不确定如何解决.

C. *_*ann 8

您似乎误解了列表构造函数的(:)作用.Haskell列表是以(:)空列表结尾的构造函数序列[],模式匹配只是以相同的顺序反汇编那些构造函数.

所以,当你在模式匹配(yf:(y:yl)),你其实是匹配至少两个元素的列表,yf并且y,和yl作为列表的其余部分.

推断类型不是您所期望的,因为length yf暗示 - 这yf是输入列表的第一个元素 - 本身就是一个列表.

您需要做的是以递归方式向下遍历列表,使用输入的当前元素或替换元素x在到达正确位置时构建新列表.一般表单看起来应该像标准库函数map,它实现如下:

map _ [] = []
map f (x:xs) = f x : map f xs
Run Code Online (Sandbox Code Playgroud)

除了你需要一种方法来跟踪你正在搜索的索引,而不是转换每个元素.

如果应用于0或1个元素的列表,您当前的函数也将失败,但在整体修改算法后,修复它应该很容易.