我刚刚开始学习 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)
我发现自己在尝试适应这种新的编程“范式”时感到非常沮丧,我所做的大部分事情都是通过反复试验来完成的。尽管我已经阅读了有关此 website 的文档,但我显然没有正确理解 map
,但所有示例都显示在控制台中,例如 map (2+) [1,2,3]
在函数中使用它们时,效果并不那么明显。
我可以得到一些关于我的 map
实现中哪里出错的指示吗?谢谢
最佳答案
发现问题的最好方法是查看类型:
rotate :: Dimensions -> ImgBlock -> [(ImgBlock,Int)]
makeAllRotations :: Dimensions -> [ImgBlock] -> [(ImgBlock,Int)]
map :: (a -> b) -> [a] -> [b]
concat :: [[a]] -> [a]
map 函数尝试对旋转返回的列表中的每个 (ImgBlock,Int) 对调用 concat。但 concat 期望获得一个嵌套列表作为其参数。但帮助我弄清楚如何修复它的最重要的事情是查看rotate d ib
。旋转的第二个参数是 ImgBlock,但在该上下文中是 ib::[ImgBlock]。当需要单个项目时,您无法传递列表。但这就是 map 功能的用途。它允许您采用接受单个项目(上面类型签名中的“a”)的函数,并在有 [a] 时使用该函数。我怀疑你想要的是这样的:
makeAllRotations d ib = concat $ map (rotate d) ib
因为rotate返回一个列表,所以map (rotate d) ib
返回一个列表列表,它非常适合作为concat函数的第一个参数。
关于Haskell Map函数实现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5809246/