Haskell Swagger Lens 自动生成
Haskell Swagger Lens autogeneration
我有以下代码:
import Control.Lens ((&), (.~), (?~), (%~))
import Data.Swagger (Swagger)
import Data.Swagger.Lens (paths, operationId, info, description)
import qualified Data.HashMap.Strict.InsOrd as InsOrdHashMap
import Data.Text (Text(..), pack)
genOpIds :: Swagger -> Swagger
genOpIds = paths %~ InsOrdHashMap.mapWithKey (\k v -> v & operationId ?~ (pack "hello"))
生成以下编译错误:
• No instance for (Data.Swagger.Lens.HasOperationId
Data.Swagger.Internal.PathItem (Maybe Text))
arising from a use of ‘operationId’
• In the first argument of ‘(?~)’, namely ‘operationId’
In the second argument of ‘(&)’, namely
‘operationId ?~ (pack "hello")’
In the expression: v & operationId ?~ (pack "hello")
|
12 | genOpIds = paths %~ InsOrdHashMap.mapWithKey (\k v -> v & operationId ?~ (pack "hello"))
| ^^^^^^^^^^^
我发现它有点难以诊断,因为我认为 makeLenses 用于生成 class 实例。我正在努力看看这与以下内容有何不同(编译得很好):
writeInfoTitle :: Swagger -> Swagger
writeInfoTitle = info.description ?~ (pack "whatever description")
因为涉及的类型层次结构在底部是相似的。我怀疑我在这里缺少一些基本的理解,但我已经阅读了镜头教程,包括遍历部分; servant swagger 代码的各种位,以及其他一些示例,但还没有弄清楚。
要轻松地重新创建错误消息,您可以克隆以下存储库和 stack build
:
https://github.com/msk-/improved-spork
免责声明:我从未使用过 Swagger。
但是,查看它的文档,我可以在 Swagger 类型中看到以下元素:
_swaggerPaths :: InsOrdHashMap FilePath PathItem
- 对应paths
镜头。
查看 PathItem
的定义表明它不是 HasOperationId
的实例 - 它本身由
组成
PathItem
_pathItemGet :: Maybe Operation
_pathItemPut :: Maybe Operation
_pathItemPost :: Maybe Operation
_pathItemDelete :: Maybe Operation
_pathItemOptions :: Maybe Operation
_pathItemHead :: Maybe Operation
_pathItemPatch :: Maybe Operation
_pathItemParameters :: [Referenced Param]
这似乎表明您在
中缺少镜头构图
(\k v -> v & (??? . operationId) ?~ (pack "hello"))
;类似于
(\k v -> v & (itemGet . operationId) ?~ (pack "hello"))
编辑:
看起来你想要实现的目标(设置一个简单的路径操作)可以通过使用 PathItem
记录的 Monoid
实例轻松完成,如下所示:
genOpsId = paths %~ InsOrdHashMap.mapWithKey (\k v -> v & get ?~ (mempty & operationId ?~ (pack "hello")))
编辑#2:
根据要求,这是一种遍历 PathItem
记录的字段并设置存在的字段的 operationId 的方法。
作为记录,我很确定有一种方法、方法、更清洁的方法来做到这一点,但这里是。
dokey :: PathItem -> PathItem
dokey v = foldl
(\acc nv -> acc & nv %~ (fmap $ operationId ?~ (pack "hello")))
v
[get, put, post, delete, options, head_, patch]
genOpIds :: Swagger -> Swagger
genOpIds = paths %~ InsOrdHashMap.mapWithKey (\k -> doKey)
希望对您有所帮助! :)
我有以下代码:
import Control.Lens ((&), (.~), (?~), (%~))
import Data.Swagger (Swagger)
import Data.Swagger.Lens (paths, operationId, info, description)
import qualified Data.HashMap.Strict.InsOrd as InsOrdHashMap
import Data.Text (Text(..), pack)
genOpIds :: Swagger -> Swagger
genOpIds = paths %~ InsOrdHashMap.mapWithKey (\k v -> v & operationId ?~ (pack "hello"))
生成以下编译错误:
• No instance for (Data.Swagger.Lens.HasOperationId
Data.Swagger.Internal.PathItem (Maybe Text))
arising from a use of ‘operationId’
• In the first argument of ‘(?~)’, namely ‘operationId’
In the second argument of ‘(&)’, namely
‘operationId ?~ (pack "hello")’
In the expression: v & operationId ?~ (pack "hello")
|
12 | genOpIds = paths %~ InsOrdHashMap.mapWithKey (\k v -> v & operationId ?~ (pack "hello"))
| ^^^^^^^^^^^
我发现它有点难以诊断,因为我认为 makeLenses 用于生成 class 实例。我正在努力看看这与以下内容有何不同(编译得很好):
writeInfoTitle :: Swagger -> Swagger
writeInfoTitle = info.description ?~ (pack "whatever description")
因为涉及的类型层次结构在底部是相似的。我怀疑我在这里缺少一些基本的理解,但我已经阅读了镜头教程,包括遍历部分; servant swagger 代码的各种位,以及其他一些示例,但还没有弄清楚。
要轻松地重新创建错误消息,您可以克隆以下存储库和 stack build
:
https://github.com/msk-/improved-spork
免责声明:我从未使用过 Swagger。
但是,查看它的文档,我可以在 Swagger 类型中看到以下元素:
_swaggerPaths :: InsOrdHashMap FilePath PathItem
- 对应paths
镜头。
查看 PathItem
的定义表明它不是 HasOperationId
的实例 - 它本身由
PathItem
_pathItemGet :: Maybe Operation
_pathItemPut :: Maybe Operation
_pathItemPost :: Maybe Operation
_pathItemDelete :: Maybe Operation
_pathItemOptions :: Maybe Operation
_pathItemHead :: Maybe Operation
_pathItemPatch :: Maybe Operation
_pathItemParameters :: [Referenced Param]
这似乎表明您在
中缺少镜头构图
(\k v -> v & (??? . operationId) ?~ (pack "hello"))
;类似于
(\k v -> v & (itemGet . operationId) ?~ (pack "hello"))
编辑:
看起来你想要实现的目标(设置一个简单的路径操作)可以通过使用 PathItem
记录的 Monoid
实例轻松完成,如下所示:
genOpsId = paths %~ InsOrdHashMap.mapWithKey (\k v -> v & get ?~ (mempty & operationId ?~ (pack "hello")))
编辑#2:
根据要求,这是一种遍历 PathItem
记录的字段并设置存在的字段的 operationId 的方法。
作为记录,我很确定有一种方法、方法、更清洁的方法来做到这一点,但这里是。
dokey :: PathItem -> PathItem
dokey v = foldl
(\acc nv -> acc & nv %~ (fmap $ operationId ?~ (pack "hello")))
v
[get, put, post, delete, options, head_, patch]
genOpIds :: Swagger -> Swagger
genOpIds = paths %~ InsOrdHashMap.mapWithKey (\k -> doKey)
希望对您有所帮助! :)