Haskell: для каждого (k,v) в Map выполните IO() с помощью k и v
У меня есть Map (Int,Int) Char
и я пытаюсь нарисовать каждый Char
S в нем в положении, содержащемся в ключе. Мои функции:
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 ответа
Твоя лямбда, \(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
иметь список (key, value)
,
Окончательный результат:
drawMirrors :: SM.Map (Int,Int) Char -> IO()
drawMirrors mirrors = do
mapM_ (\((x,y), c) -> drawMirror c (Position x y)) $ SM.toList mirrors
Я играл с этим, и нашел один способ использовать 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
,