我正在编写data
条记录以对JIRA
JSON
个对象进行编组。问题是,多个对象具有相同的名称/值对标签。例如:
(从curl返回并格式化)
{"expand":"schema,names"
,"startAt":0
,"maxResults":2
,"total":74
,"issues":[
{"expand":"editmeta,renderedFields,transitions,changelog,operations"
,"id":"183614"
,"self":"https://10.64.16.44/rest/api/latest/issue/183614"
,"key":"BNAP-339"
,"fields":{"versions":[
{"self":"https://10.64.16.44/rest/api/2/version/28240"
,"id":"28240"
,"name":"2012-12-07"
,"archived":false
,"released":false
}
]
,"status":{"self":"https://10.64.16.44/rest/api/2/status/1"
,"description":"The issue is open and ready for the assignee to start work on it."
,"iconUrl":"https://10.64.16.44/images/icons/status_open.gif"
,"name":"Open"
,"id":"1"
}
,"description":"Do Re Mi Fa"
,"resolution":null
}
}
]
当我构造有问题的相应Haskell data
记录时,我得到:
data Issue = Issue {expand :: String
,id :: String
,self :: String
,key :: String
,fields :: Fields
} deriving Generic
data Version = Version {self :: String
,id :: String
,name :: String
,archived :: Bool
,released :: Bool
} deriving Generic
和'id'和'self'会发生冲突。它发生在我身上我只需更改记录中的名称并使用手动创建的FromJSON
实例进行修复即可解决此问题。
任何替代解决方案都是受欢迎的。
答案 0 :(得分:10)
我在协议缓冲区中通过将Issue
和Version
之类的内容放在同一层次结构中的单独文件中来解决此问题。
Haskell只使用单独的模块来控制名称空间,因此这是正统的解决方案。
非常有趣:使用类型类来定义可用名称:
class Has'self a b | a -> bwhere
get'self :: a -> b
set'self :: b -> a -> b
instance Has'self Issue String where ...
instance Has'self Version String where ....
编辑:以下评论提醒我提供更详细的建议。不要使用Has'self喜欢的解决方案 - 那些已经走过那条道路报告它变得难看。我可以保证单独模块的路径。
PS:也许你可以在你的领域使用lens库!
答案 1 :(得分:3)
另一个应该起作用的替代方法是使用包含不同记录的单个数据类型。例如,以下数据类型能够表示您的值而不会发生字段冲突:
import Prelude hiding (id)
data JIRA = JIRA
{ expand :: String
, startAt :: Int
, maxResults :: Int
, total :: Int
, issues :: [JIRA]
} | Issue
{ expand :: String
, id :: Int
, self :: String
, key :: String
, fields :: JIRA
} | Field
{ versions :: [JIRA]
, status :: JIRA
, description :: String
, resolution :: Maybe String
} | Version
{ self :: String
, id :: Int
, name :: String
, archived :: Bool
, released :: Bool
} | Status
{ self :: String
, description :: String
, iconUrl :: String
, name :: String
, id :: Int
}
yourExample = JIRA
{ expand = "schema, names"
, startAt = 0
, maxResults = 2
, total = 74
, issues = [ Issue
{ expand = "editmeta, etc..."
, id = 12345
, self = "https://xyz"
, key = "BLAH"
, fields = Field
{ versions = [ Version
{ self = "https://foobar"
, id = 1234
, name = "quux"
, archived = False
, released = False
}
]
, status = Status
{ self = "https://etc"
, description = "issue"
, iconUrl = "https://iconurl"
, name = "open"
, id = 1
}
, description = "another description"
, resolution = Nothing
}
}
]
}