[英]Haskell: Couldn't match type ‘IO’ with ‘[]’ when using parseFileExif
Playing around with Haskell I'm trying to build a script that takes paths to image files and outputs the EXIF creation date of these files. 与Haskell一起玩我正在尝试构建一个脚本,该脚本采用指向图像文件的路径并输出这些文件的EXIF创建日期。 The
photoProcess
function of the following module is called from the executable: 从可执行文件中调用以下模块的
photoProcess
函数:
module Lib
( photoProcess
) where
import Graphics.HsExif
import Data.Time.Format
import Data.Time.LocalTime
import Data.Map
photoProcess :: [FilePath] -> IO ()
photoProcess arguments = putStrLn ("photoProcess: " ++ (unwords (getDateStringFromFileList arguments)))
getDateStringFromFileList :: [FilePath] -> [String]
getDateStringFromFileList = fmap getDateStringFromFile
getDateStringFromFile :: FilePath -> String
getDateStringFromFile filePath = do
exifData <- parseFileExif filePath
exifToString exifData
exifToString :: Either String (Map ExifTag ExifValue) -> String
exifToString (Left message) = message
exifToString (Right exifMap) = timeToString exifMap
timeToString :: Map ExifTag ExifValue -> String
timeToString exifMap = case getDateTimeOriginal exifMap of
Just localTime -> formatTime defaultTimeLocale "%m/%d/%Y %I:%M %p" localTime
Nothing -> "Nothing"
I know the script has several errors but I do not know how to find or fix them. 我知道脚本有几个错误,但是我不知道如何查找或修复它们。
stack build
says: stack build
说:
• Couldn't match type ‘IO’ with ‘[]’
Expected type: [Either String (Map ExifTag ExifValue)]
Actual type: IO (Either String (Map ExifTag ExifValue))
• In a stmt of a 'do' block: exifData <- parseFileExif filePath
In the expression:
do { exifData <- parseFileExif filePath;
exifToString exifData }
In an equation for ‘getDateStringFromFile’:
getDateStringFromFile filePath
= do { exifData <- parseFileExif filePath;
exifToString exifData }
The main problem seems to be 主要问题似乎是
exifData <- parseFileExif filePath
Where is the list from the error message coming from? 错误消息列表从何而来? Why expect a list?
为什么要列出清单?
Testing the types in GHCI I get: 测试GHCI中的类型,我得到:
Prelude Graphics.HsExif> :t parseFileExif path
parseFileExif path
:: IO
(Either
String (containers-0.5.7.1:Data.Map.Base.Map ExifTag ExifValue))
Prelude Graphics.HsExif> test <- parseFileExif path
Prelude Graphics.HsExif> :t test
test
:: Either
String (containers-0.5.7.1:Data.Map.Base.Map ExifTag ExifValue)
What am I missing here? 我在这里想念什么?
Your type signature says 您的类型签名说
getDateStringFromFile :: FilePath -> String
String
is [Char]
, which is a list. String
是[Char]
,它是一个列表。
getDateStringFromFile filePath = do
Therefore here the compiler expects all statements of this do
block to have a list type. 因此,在此编译器期望此
do
块的所有语句都具有列表类型。
Did you mean IO String
? 您是说
IO String
吗?
In that case exifToString exifData
has the wrong type (no IO
), so you'd have to use return
: 在这种情况下,
exifToString exifData
的类型错误(没有IO
),因此您必须使用return
:
return (exifToString exifData)
The issue is that getDateStringFromFile
implementation is wrong, it should be something like: 问题是
getDateStringFromFile
实现是错误的,应该是这样的:
getDateStringFromFile :: FilePath -> IO String
getDateStringFromFile filePath = do
exifData <- parseFileExif filePath
return $ exifToString exifData
At that point you could use the new getDateStringFromFile
like this: 那时,您可以像下面这样使用新的
getDateStringFromFile
:
photoProcess :: [FilePath] -> IO ()
photoProcess arguments = do
dateStrings <- getDateStringFromFileList arguments
putStrLn ("photoProcess: " ++ (unwords dateStrings))
getDateStringFromFileList :: [FilePath] -> IO [String]
getDateStringFromFileList = mapM getDateStringFromFile
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.