如何在将类型族存储到 json 后对其进行验证?

How to validate type family after storing it in json?

以下代码无法编译并给出

的错误

Couldn't match type ‘c1’ with ‘c’ ‘c1’ is a rigid type variable bound by a pattern with constructor: SomeReq :: forall c. Conn c => Req c -> SomeReq, in an equation for ‘run’

{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ExistentialQuantification #-}

module Main where

import qualified Data.Text as T

class Conn c where
  data Auth c :: *
  data Env c :: *
  data Req c :: *

  getEnv :: Auth c -> IO (Env c)
  runReq :: Env c -> Req c -> IO String

data SomeAuth = forall c. (Conn c) => SomeAuth (Auth c)
data SomeReq = forall c. (Conn c) => SomeReq (Auth c)

run :: SomeAuth -> SomeReq -> IO String
run (SomeAuth auth) (SomeReq req) = do
  env <- getEnv auth
  runReq env req

main :: IO ()
main = return ()

存在性的原因是我需要将这些数据类型存储在json中。 (Auth c)(Req c) 总是分开存储,但总是一起使用。

我假设完成这项工作的唯一可能方法是进行某种运行时检查以验证这些类型是否匹配。不过我不确定该怎么做。

给定一个 SomeAuth 和一个 SomeReq,你无法确定它们包装的类型是否相同。如果有有限多种可能性(一个有限的"universe"),那么你可以用一个GADT来标记它们:

data CTag c where
  C1T :: CTag C1
  C2T :: CTag C2
  ...

SomeAuth 中添加一个 CTag,在 SomeReq 中添加一个并进行模式匹配。

如果 c 可以是任何旧东西,你最好的选择是使用 Data.Typeable,向 SomeAuthSomeReq 添加一个 Typeable 约束构造函数。一旦您同时打开它们,您将能够确定类型是否匹配,如果匹配则获取证据。