我有一个使用Aeson从文件内的json对象获取数据的函数。 数据和功能均在下面定义。

data Data = Data { date :: String
                   , temperature :: Int
                    } deriving (Show, Read, Generic)

data Temperatures = Temperatures { temperatures :: [Data]
                                 } deriving (Show, Generic)

mooStuff :: IO Temperatures
mooStuff  = decode <$> getFile
    where
        getFile = B.readFile "Hello.txt"

该函数正在使用的文件包含:

Data {date = "2015-02-28T20:16:12+00:00", temperature = 0}
Data {date = "2015-01-01T21:46:55+00:00", temperature = 2}
Data {date = "2015-04-08T21:46:53+00:00", temperature = 3}
Data {date = "2015-04-09T21:46:01+00:00", temperature = 4}
Data {date = "2015-04-10T21:46:40+00:00", temperature = 5}
Data {date = "2015-04-11T21:46:36+00:00", temperature = 6}
Data {date = "2015-04-12T20:36:25+00:00", temperature = 7}

但是我收到类型错误:

test.hs:37:13:
    Couldn't match type ‘Maybe a0’ with ‘Temperatures’
    Expected type: B.ByteString -> Temperatures
      Actual type: B.ByteString -> Maybe a0
    In the first argument of ‘(<$>)’, namely ‘decode’
    In the expression: decode <$> getFile

我已经盯着这个看了好几个小时了,无济于事。 关于我要去哪里的任何想法将不胜感激!

===============>>#1 票数:11 已采纳

该错误的原因是decode并不总是成功。 它的类型是

decode :: Data a => ByteString -> Maybe a

相应地,

(decode <$>) :: Data a => IO ByteString -> IO (Maybe a)
                          -- desired type, IO Temperatures, won't unify

类型错误消息为您提供了抽象的Maybe a0作为实际类型,因为它在Maybe接近为decode类型的Data a选择合适的实例之前就检测到MaybeTemperatures之间的冲突。

您的代码需要考虑文件传递其内容但未成功decodeTemperatures的可能性。

就像是

do mt <- decode <$> getFile
   case mt of
     Nothing -> -- handle failure here
     Just t  -> return t

或者,如果您对decode失败而触发IO “用户错误”感到满意,

do Just t <- decode <$> getFile
   return t

无论如何,您的代码都有一种无法解决的故障模式,这就是类型错误。

  ask by Bradley translate from so

未解决问题?本站智能推荐: