如何在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
符号和<-
箭头使您能够“剥离”IO
包装。因此,当您编写images <- loadPieceImages
时,编译器期望loadPieceImages
具有IO
类型。但是,loadPieceImages
的类型为 [IO Picture]
,这就是编译器抱怨的原因。最外层的包装是[]
,而不是IO
。
另一方面,如果您有一个 IO [Picture]
值,则可以使用 <-
箭头剥离 IO
包装器以“获取”其中的 [Picture]
列表.
换句话说,您需要一个类型为[IO Picture] -> IO [Picture]
的函数。您可以Hoogle that type 并考虑建议。
一旦你掌握了窍门,你就会开始注意到,每当你想“翻转”两个包装器(如 IO
和 []
)的“堆叠”时,都有一个通用函数用于那:sequence。此函数获取任何Monad m
的列表并将其翻转为m [a]
。因为IO
是Monad
实例,所以这里也可以。
所以,像
images <- sequence loadPieceImages
应该可以工作(我实际上并没有尝试编译它,因为 OP 不是 minimal reproducible example,所以你可能需要稍微调整一下,但这是一般的想法:使用 sequence
)。
【讨论】:
我想说正确的解决方法是将loadPieceImages
定义中的map
更改为mapM
(并相应地修复类型签名)。以上是关于如何在haskell(光泽)中加载图像数组?的主要内容,如果未能解决你的问题,请参考以下文章
无法在 AppDelegate 应用程序方法的数组中加载 HTTP POST 响应数据。如何解决这个问题?
如何使用 IBDesignable UIImageView 在 prepareForInterfaceBuilder 中加载图像