How to make lenses for records with type-families [duplicate]

北慕城南 提交于 2019-11-29 15:46:36

The problem here is that makeLensesFor will try to generate an instance as follows:

instance HasClientId (NewTag f) (Incoming f Int64) where
  ....

This, however, is an error because you cannot create an instance for the result of a type family application. To avoid this, we can write the instance manually for each of the two possible choices for f:

-- generate lenses _foo for each record selector foo
-- (in this case, generates _ntClientId and _ntTag lenses)
makeLensesWith (lensRules & lensField .~ mappingNamer (\x -> ['_' : x])) ''NewTag

class HasClientId s a | s -> a where
  clientId :: Lens' s a

instance HasClientId (NewTag Validated) Int64 where
  clientId = _ntClientId

instance HasClientId (NewTag ValidationErrors) (Either [T.Text] Int64) where
  clientId f a = f (ntClientId a) <&> \ntClientId' -> a { ntClientId = ntClientId' }

class HasTag s a | s -> a where
  tag :: Lens' s a

instance HasTag (NewTag Validated) Tag where
  tag = _ntTag

instance HasTag (NewTag ValidationErrors) (Either [T.Text] Tag) where
  tag = _ntTag
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!