當我想加載一個 bmp 檔案時,我這樣做:
loadBMP :: String -> IO Picture
如果不確定給定路徑是否存在,可以執行以下操作:
saveLoad :: String -> IO Picture
saveLoad str = do
b <- doesFileExist str
if b then loadBMP str
else return Blank
另一種方式也可以是;使用單子變壓器:
saveLoadM :: String -> MaybeT IO Picture
saveLoadM s = do
b <- lift $ doesFileExist s
if b then do
p <- lift$ loadBMP s
return p
else MaybeT $ return Nothing
但是您將如何處理檔案串列?
test ::[String] -> ListT IO Picture
test [] = ListT $ return []
test (x:xs) = do
b <- lift $ doesFileExist x
if b then do
p <- lift$ loadBMP x
return p -- would yield a simple [p]
-- therefore:
p : test xs -- wrong -> not working
else test xs
uj5u.com熱心網友回復:
你只需要fmap.
test :: [String] -> IO [Picture]
-- this bit as before...
if b then do
p <- loadBMP x
(p:) <$> test xs
else test xs
但是你不應該使用doesFileExist這種方式。相反,加載位圖并在檔案不存在時捕獲例外;這可以防止競爭條件。
test (x:xs) = do
imgE <- try (loadBMP x)
case imgE of
Right img -> (img:) <$> test xs
Left err | isDoesNotExistError err -> test xs
| otherwise -> throwIO err -- reraise other exceptions
如果你對擴展沒問題,我覺得匿名案例很適合這里。
test (x:xs) = try (loadBMP x) >>= \case
Right img -> ...
Left err | ...
| ...
uj5u.com熱心網友回復:
您可以使用package witherable,如下所示:
import Witherable
test :: [String] -> IO [Picture]
test = wither $ \x -> do
b <- doesFileExist x
if b then do
p <- loadBMP x
return $ Just p
else return Nothing
為了直觀地理解什么wither意思,想象一下如果它被命名mapMaybeM了。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/475117.html
標籤:哈斯克尔
