0

我想使用一堆硬编码名称和现有函数加载图像列表(或任何数据结构)loadImage :: String -> IO Image

在 Lua 中,我会执行以下操作:

imageNames = {"background", "gun", "man"}

images = {}
for i,v in ipairs(imageNames) do
    images[v] = loadImage(v..".png")
end

并使用等访问它们images.backgroundimages.man我怎么能在 Haskell 中解决这个问题?

4

3 回答 3

3
import Data.Map

imageNames :: [String]
imageNames = ["background", "gun", "man"]

images :: [IO (String, Image)]
images = [loadImage(name ++ ".png") >>= return . (,) name | name <- imageNames]

main = do
  imgs <- sequence images
  let imageMap = fromList imgs
  return ()

imageMap 是一个Map您可以通过其名称访问图像的方法:imageMap ! "gun"

于 2013-08-31T06:32:28.103 回答
2

基本上正如 Ankur 所说,我可能没有明确的“图像”列表,并且可能会使用 JuicyPixels 进行加载:

import Data.Map
import Codec.Picture

images :: [String]
images = ["background", "gun", "man"]

main = do
  imgs <- mapM loadImage images
  let imageMap = fromList (zip images imgs)
  return ()

loadImage :: IO DynamicImage
loadImage = either id (error "Bad Image") `fmap` readImage
于 2013-08-31T08:59:07.057 回答
0

我参加聚会有点晚了,但这是另一种方法。它的工作原理与其他解决方案略有不同,但最终结果是相同的。

import Data.Map (insert, empty)
import Data.List (foldl')
import Control.Applicative ((<$>))
import Control.Monad (forM)

imageNames = ["background", "gun", "man"]

images = foldl' (flip id) empty <$> forM imageNames (\name ->
    insert name <$> loadImage (name ++ ".png")
  )

它的作用是images构建一个insert等待在Map. 然后它用于通过操作列表对foldl'a 进行线程化。随着折叠的进行,它使用操作来构建一个越来越大的所需值。换句话说,这不会构建一个中介,然后将其转换为.MapinsertinsertMap[(String, Image)]Map String Int

用andIOloadImage外部函数一直传递到,给出结果类型。<$>sequenceIO (Map String Image)

我认为其他解决方案更容易阅读(并且可能也更有效),所以我推荐其中一个。我只是想把这个扔出去。

于 2013-09-01T13:27:54.247 回答