尝试返回删除了最后一个元素的列表。为什么我收到此错误?
ERROR file:.\ShrinkByOne.hs:5 - Type error in application
*** Expression : (lis !! n : result) lis n
*** Term : (:)
*** Type : f -> [f] -> [f]
*** Does not match : a -> b -> c -> d -> e
shrinkByOne :: [Int] -> [Int] -> Int -> [Int]
shrinkByOne result lis n
| n <= ((length lis) - 2) = shrinkByOne ( ((lis !! n):result) lis n+1) -- this condition prevents the last element from being returned
| otherwise = result
答案 0 :(得分:8)
在您的原始代码中,您有类似的内容:
shrinkByOne (... something ...)
这意味着您只对shrinkByOne
应用了一个参数。你需要这个:
shrinkByOne (... something ...) (... something ...) (... something ...)
因此,以这种方式放括号:
shrinkByOne :: [Int] -> [Int] -> Int -> [Int]
shrinkByOne result lis n
| n <= ((length lis) - 2) = shrinkByOne ((lis !! n):result) lis (n+1) -- this condition prevents the last element from being returned
| otherwise = result
但是,您仍然无法获得所需的结果,因为结果将被反转,!!
代价昂贵,并且您的函数将具有Θ(n²)复杂度。
尝试更简单的线性方法:
shrinkByOne' :: [Int] -> [Int]
shrinkByOne' [x] = []
shrinkByOne' (x : xs) = x : shrinkByOne' xs
最后,我明白这是学习Haskell的练习。如果不是,只需使用Prelude中的init
函数。
答案 1 :(得分:4)
首先,你想在函数参数周围省略不必要的parens。 f(x)
在Haskell中写成f x
(一个只是可选的),特别是如果g (x y)
你不能写g :: A -> B -> C
,它必须是g x y
(或者g (x) (y)
。但是g (x y)
意味着,您将函数x
应用于参数y
,并将结果用作g
的参数。(如果您确实需要,请写下g $ x y
或g . x $ y
。)
这意味着shrinkByOne ((lis !! n):result) lis n+1
。但是,哪个会被解析为(shrinkByOne ((lis !! n):result) lis n) + 1
:像+
这样的中缀运算符总是比函数应用程序具有更低的优先级,所以确实在n+1
周围你需要parens。