Haskell 哈斯克尔招摇过市镜头自动生成
我有以下代码:Haskell 哈斯克尔招摇过市镜头自动生成,haskell,swagger,haskell-lens,Haskell,Swagger,Haskell Lens,我有以下代码: 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) gen
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"))
| ^^^^^^^^^^^
我发现诊断起来有点困难,因为我认为MakeLens用于生成类实例。我有点难以理解这与下面的(编译得很好)有什么不同:
因为所涉及的类型层次结构在底部是相似的。我怀疑这里缺少一点基本的理解,但我已经阅读了镜头教程,包括关于遍历的部分;各种各样的仆人招摇过市的代码,还有一些其他的例子,都还没有弄明白这一点
要轻松地重新创建错误消息,您可以克隆以下repo和堆栈构建
:
https://github.com/msk-/improved-spork
免责声明:我从不招摇过市。 但是,查看文档,我可以看到招摇过市类型中的以下元素:
\u swaggerPaths::InsOrdHashMap FilePath PathItem
-对应于路径
镜头。查看
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
记录的字段,并设置当前字段的操作ID。
为了记录在案,我非常肯定有一种方法,一种方法,一种更干净的方法来做到这一点,但现在开始
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)
希望有帮助!:) 您已经确定了问题所在,非常感谢。这有点尴尬,甚至和我想象的不一样!如您所见,PathItem可能包含多个操作。我想在任何存在操作ID的地方插入操作ID。我尝试过以各种组合使用traverse,以及每种组合,例如,
genOpsId=path%~InsOrdHashMap.mapWithKey(\k v->v.traverse?~(mempty&operationId?~(pack“hello”))
)。你知道我怎样才能做到吗?另外,我对mempty&operationId
在做什么有点困惑,你知道我可能会读些什么来理解这一点吗?谢谢不要介意第二个问题,得到mempty&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)