简体   繁体   English

Haskell:使用parseFileExif时无法将类型“ IO”与“ []”匹配

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM