为什么会抛出错误?
myTest :: Int -> [Int]
myTest a
| a == 0 = []
| otherwise = x ++ map(myTest) x
where x = [a-1]
我希望它会使列表从a变为1.相反,我得到错误:
couldn't match the expected type 'Int' against inferred type '[Int]'
in the first argument of 'map', namely '(myTest)'
in the second argument of '(++)', namely 'map (myTest) x'
这显然不是制作此列表的最佳方式,但它是我遇到的更复杂问题的简化版本。
我基本上有一个函数foo :: a -> [a]
,在结果列表中,我需要在每个元素上调用foo
,将它扩展到另一个列表中。最后,我想要一个大的列表,其中每个元素都是基本情况。
我在Haskell相当新,所以我可能错过了一些相当基本的东西。
答案 0 :(得分:3)
myTest
的签名是Int -> [Int]
。
map
的签名为(a -> b) -> [a] -> [b]
,由于myTest
是第一个参数,因此(Int -> [Int]) -> [Int] -> [[Int]]
。
但是您的函数希望它生成[Int]
,而不是[[Int]]
。
编辑添加:我认为您想要的只是
myTest a
| a == 0 = []
| otherwise = [a] ++ myTest (a-1)
虽然这可能不是你应该想要的东西(它比惯用的Haskell解决方案更重要),但是没有看到你的实际问题,这是一个简化,它&# 39;很难说。
答案 1 :(得分:2)
myTest :: Int -> [Int]
myTest 0 = []
myTest a = a : myTest (a-1)
答案 2 :(得分:2)
Else的答案更好,因为使用(:)代替(++)。在你的情况下,你可以使用,因为(:)在列表的前面添加一个元素,这就是你想要做的。
(++)是一个相对昂贵的操作,因为它复制了左手列表的脊柱。 (:)很便宜,因为它从不复制任何东西,它只是创建一个包含新头元素的新cons单元格。
如果可以的话,总是使用(:)代替(++)。
编辑:只是试图解释,因为Else没有发布他的代码的解释。