2017-03-02 68 views
0

我最近开始与Haskell玩,似乎无法找出这一个。Haskell从YAML文件中读取嵌套的时间戳

我试图从具有这种格式的YAML文件读取:

id: 1 
kind: good 
created_at: !ruby/object:ActiveSupport::TimeWithZone 
    utc: &1 2017-01-01 10:34:12.533704000 Z 
    zone: &2 !ruby/object:ActiveSupport::TimeZone 
    time: *2 

到目前为止,我可以做这个读取ID和那种完美的罚款:

data Item= Item{ 
    id :: Integer, 
    kind::String 
    } 

而且

instance FromJSON Item where 
    parseJSON(Object v) = Item <$> 
     v .: "id" <*> 
     v .: "kind" 

我正在使用软件包“Data.Yaml”,此功能:
let items = Data.Yaml.decode ymlData :: Maybe[Item]

但我似乎无法弄清楚如何获得时间戳。

什么是获得时间戳的正确方法,只需要“utc”。

+1

我看到的第一个问题是你必须大写你的类型和构造函数,所以'data Item = Item ...'和'instance FromJSON Item where ...'。我认为你的问题实际上是关于如何访问嵌套元素,这是你真正想问什么?这个问题似乎并不是关于获取时间戳,而是关于如何在YAML中使用嵌套结构。 – bheklilr

+0

@bheklilr谢谢你的回应,是的,你是对的。这个问题的确应该是:“如何访问嵌套元素?” – QuickQuestionGuy

+0

您是否使用[* yaml *包](https://hackage.haskell.org/package/yaml-0.8.9/docs/Data-Yaml.html)?如果是这样,你应该在问题中提到它。 (顺便说一下,你可以编辑它来添加说明。) – duplode

回答

2

最简单的方法是创建一个newtype实现FromJSON

import Data.Time 
import Data.Yaml 

data Item = Item 
    { id :: Int 
    , kind :: String 
    , createdAt :: UTCTime 
    } deriving (Show) 

instance FromJSON Item where 
    parseJSON (Object v) = 
    Item <$> v .: "id" <*> v .: "kind" <*> v .: "created_at" 

newtype Time = Time String deriving (Show, Eq) 

instance FromJSON Time where 
    parseJSON (Object v) = Time <$> v .: "utc" 

希望有所帮助。

+2

值得注意的是['UTCTime'有一个'FromJSON'实例](https://hackage.haskell.org/package/aeson-1.1.0.0/docs/Data-Aeson.html#t:FromJSON),并且所以在'Time'的定义中用'UTCTime'替换'String'将会正常工作,不需要进一步的改变。 – duplode

+0

啊!感谢您指出了这一点。我没有意识到。 – Erik

+0

@Erik这个作品,谢谢你的帮助! – QuickQuestionGuy