Haskell Map函数实现问题

时间:2011-04-27 19:10:24

标签: haskell map compiler-errors concatenation

我刚刚开始学习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

1 个答案:

答案 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函数的第一个参数。