如何在haskell(光泽)中加载图像数组?

Posted

技术标签:

【中文标题】如何在haskell(光泽)中加载图像数组?【英文标题】:How to load array of images in haskell(gloss)? 【发布时间】:2022-01-11 11:16:16 【问题描述】:

我对 Haskell 很陌生,目前对 monad 还不太了解。我正在使用光泽来制作国际象棋。我面临的问题是加载多个图像。我正在使用haskell 提供的loadBMP 函数来加载图像。它的签名是:

loadBMP :: FilePath -> IO Picture

我可以加载单个图像,但无法加载图像数组。

-- This function calculates the path of all the images and then apply loadBMP function on it.

loadPieceImages :: [IO Picture]
loadPieceImages = do
  map (loadBMP . (\n -> "images/" ++ n ++ ".bmp") . (\n -> if n < 6 then show n ++ "-w" else show (n `mod` 6) ++ "-b")) [0 .. 12]

main :: IO ()
main = do
  images <- loadPieceImages  -- On this line I am getting error.
  play window (makeColor 1 0 0 1) 30 initialState draw transform (const id)

主要问题是我有[IO Picture] 类型,但我不知道如何将它变成[Picture]

这东西可能很基础,但我现在无法理解单子。所以请解释一下你给出的答案。

【问题讨论】:

【参考方案1】:

由于您(正确地)将main 声明为IO ()do 符号和&lt;- 箭头使您能够“剥离”IO 包装。因此,当您编写images &lt;- loadPieceImages 时,编译器期望loadPieceImages 具有IO 类型。但是,loadPieceImages 的类型为 [IO Picture],这就是编译器抱怨的原因。最外层的包装是[],而不是IO

另一方面,如果您有一个 IO [Picture] 值,则可以使用 &lt;- 箭头剥离 IO 包装器以“获取”其中的 [Picture] 列表.

换句话说,您需要一个类型为[IO Picture] -&gt; IO [Picture] 的函数。您可以Hoogle that type 并考虑建议。

一旦你掌握了窍门,你就会开始注意到,每当你想“翻转”两个包装器(如 IO[])的“堆叠”时,都有一个通用函数用于那:sequence。此函数获取任何Monad m 的列表并将其翻转为m [a]。因为IOMonad 实例,所以这里也可以。

所以,像

images <- sequence loadPieceImages

应该可以工作(我实际上并没有尝试编译它,因为 OP 不是 minimal reproducible example,所以你可能需要稍微调整一下,但这是一般的想法:使用 sequence )。

【讨论】:

我想说正确的解决方法是将loadPieceImages 定义中的map 更改为mapM(并相应地修复类型签名)。

以上是关于如何在haskell(光泽)中加载图像数组?的主要内容,如果未能解决你的问题,请参考以下文章

无法在 AppDelegate 应用程序方法的数组中加载 HTTP POST 响应数据。如何解决这个问题?

如何在处理中加载的 png 图像上创建颜色剪贴蒙版?

如何等待在画布中加载图像

当枢轴选择更改时,如何在枢轴项目中加载图像后加载音频文件

如何使用 IBDesignable UIImageView 在 prepareForInterfaceBuilder 中加载图像

如何在 Codeigniter 中加载图像?