首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >实例减速中的变量类型(Aeson)

实例减速中的变量类型(Aeson)
EN

Stack Overflow用户
提问于 2016-03-19 19:37:46
回答 1查看 125关注 0票数 0

我有JSON数据,可能看起来像这样

代码语言:javascript
复制
{
"items": [Day],
"pageCount": Int,
"totalCount": Int
}

或者这个

代码语言:javascript
复制
{
"items": [Order],
"pageCount": Int,
"totalCount": Int
}

我一直试图为FromJSON中使用的不可更改的字段创建数据类型,但是在经历各种错误时,我还没有找到正确的方法。这是处于当前状态的代码。

代码语言:javascript
复制
--{-# LANGUAGE FlexibleInstances #-}
--{-# LANGUAGE MultiParamTypeClasses #-}
--{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE OverloadedStrings #-}
import           Data.Aeson

data Typed = Typed {typeID::Int,name::String} deriving (Show,Eq)
data Day =  Day {orderCount::Int,lowPrice::Float,highPrice::Float, avgPrice:: Float,volume::Int,date::String}
data Order = Order {price::Float,isBuy::Bool,location::Typed} deriving (Show,Eq)
data Market a = Market {items::a,pageCount::Int,totalCount::Int} deriving (Show,Eq)
-- Can be either Market [Order] or Market [Day]
instance FromJSON (Market a) where
  parseJSON (Object x) = Market <$> x .: "items" <*> x .: "pageCount" <*> x .: "totalCount"
instance FromJSON Order where
  parseJSON (Object x) = Order <$> x .: "price" <*> x .: "buy" <*> x .: "location"
instance FromJSON Typed where
  parseJSON (Object x) = Typed <$> x .: "id" <*> x .: "name"
instance FromJSON Day where
  parseJSON (Object x) = Day <$> x .: "orderCount" <*> x .: "lowPrice" <*> x .: "highPrice"
    <*> x .: "avgPrice" <*> x .: "volume" <*> x .: "date"

这是我目前遇到的错误

代码语言:javascript
复制
No instance for (FromJSON a) arising from a use of ‘.:’
    Possible fix:
      add (FromJSON a) to the context of the instance declaration
    In the second argument of ‘(<$>)’, namely ‘x .: "items"’
    In the first argument of ‘(<*>)’, namely ‘Market <$> x .: "items"’
    In the first argument of ‘(<*>)’, namely
      ‘Market <$> x .: "items" <*> x .: "pageCount"’
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-19 21:50:08

所以这里有两个问题。第一个是编译错误:您声称您有一个Market a实例,这意味着您知道如何为任何选择的a解析市场的JSON序列化,但这实际上是不可能的,因为您希望解析某种类型的a,以便为price字段的内容定价。

我们将注意力限制在只考虑我们知道如何通过在实例声明中添加约束来解析的可能的a

代码语言:javascript
复制
instance FromJSON a => FromJSON (Market a) where
  ...

现在一切都很好。但是,还有另一个问题,我们实现FromJSON的方式--我们看到它充满了非穷尽的匹配!尝试使用-Wall运行此命令,以查看GHC为此向我们发出的抱怨。现在的问题是,如果给出了Object以外的其他内容,那么每个Object实际上都会失败(而不是解析失败,比如“炸毁整个程序”)。这意味着我们的行为很差,比如

代码语言:javascript
复制
λ> decode "1.0" :: Maybe Typed
*** Exception: /home/jozefg/scratch/Aeson.hs:(24,3)-(25,39): Non-exhaustive patterns in function parseJSON

为了解决这个问题,我们只需添加另一个子句,在所有其他情况下都显式失败。更多的生产-y解决方案可能是不手工编写这些实例,因为它们都是非常简单的,而是使用埃森对泛型的支持。下面是Order的固定实例,例如,我刚刚添加了一个额外的子句

代码语言:javascript
复制
instance FromJSON Order where
  parseJSON (Object x) =
    Order <$> x .: "price" <*> x .: "buy" <*> x .: "location"
  parseJSON _ = mempty
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36106261

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档