我刚刚开始学习Haskell并且在调整语言方面遇到了麻烦,例如在map
的实现时更具体地说,当尝试执行类似于以下示例中的操作时;
rotate :: Dimensions -> imgBlock -> [(imgBlock,Int)]
rotate d ((p, pix), s, t)
= zip [((p, f pix), s, t) | f <- transformate (fst d)] [0..7]
makeAllRotations :: Dimensions -> [imgBlock] -> [(imgBlock,Int)]
makeAllRotations d ib = map concat (rotate d ib) //Error points Here
其中
type imgBlock = (Block, Int, Int)
type Block = (Pnt, Pxl)
type Dimensions = (Int, Int)
这是我得到的错误之一
asdf.hs:73:30:
Couldn't match expected type `(imgBlock, Int)'
with actual type `[a0]'
Expected type: [[a0]] -> (imgBlock, Int)
Actual type: [[a0]] -> [a0]
In the first argument of `map', namely `concat'
In the expression: map concat (rotate d ib)
我发现自己非常沮丧,试图适应这种新的编程“范式”,我设法做的大部分事情都是通过反复试验。我显然没有正确理解map
,虽然我已经阅读了这个website的文档,但所有示例都显示在控制台中,如map (2+) [1,2,3]
,而不是在函数中使用它们。
我可以在我的map
实施中找到关于我出错的地方的一些指示。 THKS
答案 0 :(得分:4)
找到问题的最佳方法是查看类型:
rotate :: Dimensions -> ImgBlock -> [(ImgBlock,Int)]
makeAllRotations :: Dimensions -> [ImgBlock] -> [(ImgBlock,Int)]
map :: (a -> b) -> [a] -> [b]
concat :: [[a]] -> [a]
map函数试图在rotate返回的列表中的每个(ImgBlock,Int)对上调用concat。但concat希望得到一个嵌套列表作为其参数。但帮助我弄清楚如何解决问题的重要一点是看rotate d ib
。旋转的第二个参数是ImgBlock,但在该上下文中ib :: [ImgBlock]。当预期单个项目时,您无法传入列表。但这就是地图功能的用途。它允许你接受一个接受单个项目的函数(上面的类型签名中的'a'),并在你有[a]时使用该函数。我怀疑你想要的是这样的东西:
makeAllRotations d ib = concat $ map (rotate d) ib
因为rotate返回一个列表,map (rotate d) ib
返回一个列表列表,它完全适合作为concat函数的第一个参数。