如何使用 Haskell/Aeson 中的类型函数解析多态值?

问题描述

为了提高我对 Haskell 的理解,我启动了一个个人项目,该项目允许用户组合许多不同的预定义转换,这些转换依赖于多态的环境和状态。

核心类型围绕 c 参数化的环境、结果类型 a 参数化的状态、Base 参数化的类型类 c 和确定a 的类型,以及一个类型类 Step,它提供了在 RWS monad 中定义用户可选转换的接口,并且在 ca

type Plan c a = Control.Monad.RWS.RWS (Env c) Log (State a)

data Env c = Env c (Set Condition)

data State a = State a (Set Constraint)

class Base c b a | b -> a where
  execBase :: Env c -> b -> (State a,Log)

class Step c a s where
  defineStep :: s -> Plan c a ()
-- ^ Plans get folded into a single plan with >>

execPlan :: (Base c b a) => Env c -> b -> Plan c a () -> (a,Log)

代码库的其余部分主要定义了几种不同的数据类型,用户可以插入到 cEnv 部分,一些数据类型可以作为结果 a,以及存在用于保存一两个参数并且是 BaseStep 实例的数据类型的 scad。问题在于我不知道如何从用户提供的 JSON 文档中解析出其中的任何内容。我开始于:

data Request c a = Request (Env c) (WrappedBase c a) [WrappedStep c a]

data WrappedBase c a where
  WrapBase :: (Base c b a,Eq b,Show b,Typeable a,Typeable b)
           => b -> WrappedBase c a

data WrappedStep c a where
  WrapStep :: (Step c a s,Eq s,Show s,Typeable s)
           => s -> WrappedStep c a

但我不知道如何说服 GHC 让我为 Data.Aeson.FromJSON 创建一个 Request c a 实例。编写一个数据类型 SomeC 很简单,它是 c 的所有可能情况的总和类型,并且几乎与为 SomeC 编写解析器和函数 {{1} 一样容易},但是我如何将其转换为 :: c -> Data.Aeson.Value -> Data.Aeson.Parser (Env c) 的解析器,以便我可以将 Env cc 中的其他 c 统一起来?>

(我也尝试将解析器转换为继续传递的样式,但是一旦我完成它,我就意识到我根本没有解决问题。)

还有更深层次的奥秘,我如何让 GHC 在值级别执行类型函数 Request,以便我可以使 Request 中的 b -> aa 指示aBase 实例,或者向用户返回一条消息,让他们知道他们选择的 b 不是为他们指定的 b 定义的?

感觉就像我想要的是使用类型相等见证,但使用类型类而不是类型 c,但我搜索了 GHC 的扩展丛,但没有找到允许这样做的东西。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)