我正在尝试使用PackageImports
扩展程序“遮蔽”Scotty模块。
使用案例:对于使用库X
的人,可以使instrumentedX
可用。因此,只需将cabal文件中的X
更改为instrumentedX
,即可使用该库的检测版本,而无需对代码进行任何其他更改。
这是我要导出的模块,它与Scotty导出的原始模块具有相同的名称,即Web.Scotty.Trans
。
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE PackageImports #-}
module Web.Scotty.Trans
(
module OS
, get
, post
, put
, delete
, patch
, options
, addroute
)
where
import qualified "scotty" Web.Scotty.Trans as OS hiding (get, post, put, delete, patch, options, addroute)
import qualified "scotty" Web.Scotty.Trans as S
import InstrumentedCore
import Control.Monad.Trans.Class(lift)
instrumentedAction original action = original action_
where
action_ = do
st <- liftIO $ getCurrentTime
result <- action
en <- liftIO $ getCurrentTime
logInstrumentationData InstrumentationData{instrStart=st, instrEnd=en, instrPayload=Render}
return result
get route action = instrumentedAction (S.get route) action
post route action = instrumentedAction (S.post route) action
put route action = instrumentedAction (S.put route) action
delete route action = instrumentedAction (S.delete route) action
patch route action = instrumentedAction (S.patch route) action
options route action = instrumentedAction (S.options route) action
addroute method route action = instrumentedAction (S.addroute method route) action
这是我的cabal文件的样子。虽然我的包依赖于scotty
,但它为自己使用了不同的包名,即instrumentedopaleye
(不要进入语义 - 我也试图影响很多其他模块!)
name: instrumentedopaleye
version: 0.1.0.0
synopsis: Initial project template from stack
description: Please see README.md
homepage: https://github.com/githubuser/dashboard#readme
license: BSD3
author: Author name here
maintainer: example@example.com
copyright: 2016 Author name here
category: Web
build-type: Simple
extra-source-files: README.md
cabal-version: >=1.10
library
hs-source-dirs: src
exposed-modules: InstrumentedOpaleye
, Instrumented
, InstrumentedOpaleye.Internal.PGTypes
, InstrumentedOpaleye.Internal.Column
, InstrumentedOpaleye.Internal.RunQuery
, InstrumentedOpaleye.Internal.HaskellDB.PrimQuery
, InstrumentedLucid
, Web.Scotty.Trans
, InstrumentedCore
build-depends: base >= 4.7 && < 5
, opaleye
, profunctors
, product-profunctors
, postgresql-simple
, mtl
, time
, stm
, text
, uuid
, lucid
, scotty
, transformers
default-language: Haskell2010
实际错误
当我尝试在GHCi中导入我的Web.Scotty.Trans
版本时会发生什么。鉴于我已明确导入仅我的Web.Scotty.Trans
版本,为什么GHCi在解决get
函数时感到困惑?即使:browse Web.Scotty.Trans
感到困惑。
Saurabhs-MacBook-Pro:instrumentedopaleye saurabhnanda$ stack exec ghci
GHCi, version 8.0.1: http://www.haskell.org/ghc/ :? for help
Prelude> :set -fobject-code
Prelude> :set -XPackageImports
Prelude> import "instrumentedopaleye" Web.Scotty.Trans
Prelude Web.Scotty.Trans> :i get
<interactive>:1:1: error:
Ambiguous interface for ‘Web.Scotty.Trans’:
it was found in multiple packages:
scotty-0.11.0 instrumentedopaleye-0.1.0.0
Prelude Web.Scotty.Trans> :browse Web.Scotty.Trans
<no location info>: error:
Ambiguous module name ‘Web.Scotty.Trans’:
it was found in multiple packages:
scotty-0.11.0@scotty-0.11.0-2sNTuGP3mb3FV66hlreoEd instrumentedopaleye-0.1.0.0@instrumentedopaleye-0.1.0.0-EAOrgrhUGi83yaJJ8gDGX4
答案 0 :(得分:2)
我在之前看到这种行为甚至你做了一个包合格的导入。例如,如果我之前已经安装了堆栈cryptonite
和crypto-api
,那么
> stack exec ghci
$ :browse Crypto.Random
导致ambiguous module name
错误。这是我遇到的一个问题;我的解决方案是使用-hide-package
标志:
> stack exec ghci
$ :set -hide-package cryptonite
$ :browse Crypto.Random
作为额外奖励,您根本不再需要PackageImports
:ghci完全忽略cryptonite
。
答案 1 :(得分:1)
根据[crockeea的回答] [1]
我没有明确地隐藏scotty
而无法在GHCi中完成这项工作
此外,由于[Haskell的模块限制] [2],无法重新导出合格的导入。因此,这就是我如何设法解决我最初的影子scotty问题:
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE PackageImports #-}
module Web.Scotty.Trans
(
module Web.Scotty.Trans -- which is the current module
, module Web.Scotty.TransOriginal -- the original module MINUS the shadowed methods
)
where
import Web.Scotty.TransOriginal
import qualified "scotty" Web.Scotty.Trans as S
import InstrumentedCore
import Control.Monad.Trans.Class(lift)
instrumentedAction original action = original action_
where
action_ = do
st <- liftIO $ getCurrentTime
result <- action
en <- liftIO $ getCurrentTime
logInstrumentationData InstrumentationData{instrStart=st, instrEnd=en, instrPayload=Render}
return result
get route action = instrumentedAction (S.get route) action
post route action = instrumentedAction (S.post route) action
put route action = instrumentedAction (S.put route) action
delete route action = instrumentedAction (S.delete route) action
patch route action = instrumentedAction (S.patch route) action
options route action = instrumentedAction (S.options route) action
addroute method route action = instrumentedAction (S.addroute method route) action
样板 Web.Scotty.TransOriginal
只需要绕过Haskell重新导出合格导入的限制:
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE PackageImports #-}
module Web.Scotty.TransOriginal
(
module Web.Scotty.Trans
)
where
import "scotty" Web.Scotty.Trans hiding (get, post, put, delete, patch, options, addroute)