Haskell:对于Map中的每个(k,v),用k和v做IO()

时间:2015-02-09 10:37:43

标签: haskell dictionary io functional-programming purely-functional

我有一个Map (Int,Int) Char,我正在尝试在密钥中包含的位置绘制每个Char。我的职责是:

import qualified Data.Map.Strict as SM
data Position = Position !GLint !GLint

drawMirrors :: SM.Map (Int,Int) Char -> IO()
drawMirrors mirrors = do
    mapM_ (\(x,y) c -> drawMirror c (Position x y)) mirrors

drawMirror :: Char -> Position -> IO()
drawMirror orientation (Position x y) = do
    -- Some irrelevant stuff

drawMirrors mirrors = do mapM_ (\(x,y) c -> drawMirror c (Position x y)) mirrors行,我收到错误:

src\Main.hs:200:33:

Couldn't match expected type `Char -> IO ()'
            with actual type `IO b0'
The lambda expression `\ (x, y) c -> drawMirror c (Position y)'
has two arguments,
but its type `(t0, GLint) -> IO b0' has only one
In the first argument of `mapM_', namely
  `(\ (x, y) c -> drawMirror c (Position y))'
In a stmt of a 'do' block:
  mapM_ (\ (x, y) c -> drawMirror c (Position y)) mirrors

我如何在drawMirrors中获取字典中的所有键和值,并将drawMirror函数应用于这些键和值?

2 个答案:

答案 0 :(得分:5)

你的lambda \(x,y) c -> drawMirror c (Position x y)有两个参数。但是,它使用(key, value)形式的单个参数调用(在您的情况下为((x, y), c)

(\((x,y), c) -> drawMirror c (Position x y))

此外,mapM_(我相信你的情况来自Data.Foldable)只会遍历密钥,所以你可能想要调用SM.toList来获得{{1}的列表}}

最终结果是:

(key, value)

答案 1 :(得分:0)

我一直在玩这个,并找到了一种方法来使用mapM_代替mapWithKeyM_。具体地,

{-# LANGUAGE GADTs #-}
{-# LANGUAGE FlexibleInstances #-}

data UnCurry :: (* -> * -> *) -> * -> * where
  UnCurry :: f k v -> UnCurry f (k, v)

instance Foldable (UnCurry Map) where
  foldr c n (UnCurry m) = M.foldrWithKey go n m
    where
      go k a b = c (k, a) b

现在,您可以使用mapM_ f (UnCurry m)Map中的每个键值对执行操作。