如何应对Haskell名称空间?

Mic*_*ard 6 json haskell jira aeson

我正在写一个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
                     }
           }
          ]
Run Code Online (Sandbox Code Playgroud)

当我构造有问题的相应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
Run Code Online (Sandbox Code Playgroud)

'id'和'self'会发生冲突.它发生在我身上我可以通过更改记录中的名称并使用手动创建的FromJSON实例修复它来解决这个问题.欢迎任何替代解决方案.

Chr*_*icz 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 ....
Run Code Online (Sandbox Code Playgroud)

编辑:下面的评论提醒我提供更详细的建议.不要使用Has'self喜欢的解决方案 - 那些已经走过那条道路报告它变得难看.我可以保证单独模块的路径.

PS:也许你可以使用镜头库为你的领域!

  • 请注意,在编写干净,结构良好的Haskell代码时,`HasFoobar`样式类型类几乎总是一个糟糕的主意.但是当尝试匹配非Haskell代码的结构以实现互操作时,如果另一方严重依赖于重载函数和/或子类型层次结构,则可能没有更好的方法. (7认同)