【发布时间】:2017-12-10 01:07:29
【问题描述】:
我正在构建代码以使用 servant 查询 REST API。对于某些端点,我希望返回值依赖于某种类型t。当我尝试使用 :<|> 组合多个此类 API 时,出现编译错误。
我试图构建一个问题的简化示例。可悲的是,最短的版本仍然不是很短。这是我的代码:
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
module Sana.ArangoDB.RTest where
import Servant.API
import Servant.Client
import Data.Aeson.Types (typeMismatch)
import Data.Proxy (Proxy(..))
import Data.Yaml (FromJSON(..), (.:))
import qualified Data.Yaml as Y
data SomeStructure t = SomeStructure { _a :: Bool , _b :: t }
instance FromJSON t => FromJSON (SomeStructure t) where
parseJSON (Y.Object v) = SomeStructure <$> v .: "a" <*> v .: "b"
parseJSON i = typeMismatch "SomeStructure" i
type MyAPI t = "api" :> Header "SomeHeader" String :> Get '[JSON] (SomeStructure t)
type MyOtherAPI t = "api2" :> Header "SomeHeader" String :> Get '[JSON] (SomeStructure t)
type TheAPI t = MyAPI t :<|> MyOtherAPI t
theAPI :: Proxy (TheAPI t)
theAPI = Proxy
queryFunction1 :: (FromJSON t ) => Maybe String -> ClientM (SomeStructure t)
queryFunction2 :: (FromJSON t ) => Maybe String -> ClientM (SomeStructure t)
queryFunction1 :<|> queryFunction2 = client theAPI
但是,这不会编译。我得到的错误是这样的:
• Couldn't match type ‘t0’ with ‘t’
because type variable ‘t’ would escape its scope
This (rigid, skolem) type variable is bound by
the inferred type for ‘queryFunction1’:
FromJSON t => Maybe String -> ClientM (SomeStructure t)
at /Users/david/devel/sana/src/Sana/ArangoDB/RTest.hs:31:1-50
Expected type: Maybe String -> ClientM (SomeStructure t)
Actual type: Maybe [Char] -> ClientM (SomeStructure t0)
有人对我如何避免此错误并使我的代码正常工作有任何建议吗?
【问题讨论】:
-
我尝试在 ghc 8.2.2 上使用
NoMonomorphismRestriction编译您的代码,它似乎工作得很好。 -
@JohnWiegley 我不需要在运行时成为
t动态。你能告诉我我必须使用的代码吗?我对Proxy t的理解还很有限,所以我真的需要一些帮助。 -
@Rufflewind 使用
NoMonomorphismRestriction为我解决了这个问题。如果你添加一个快速的答案,我会接受它:) -
@Sh4pe 既然给出了这个问题的正确答案,我已经删除了我不准确的答案。
标签: haskell