问题描述
为了提高我对 Haskell 的理解,我启动了一个个人项目,该项目允许用户组合许多不同的预定义转换,这些转换依赖于多态的环境和状态。
核心类型围绕 c
参数化的环境、结果类型 a
参数化的状态、Base
参数化的类型类 c
和确定a
的类型,以及一个类型类 Step
,它提供了在 RWS
monad 中定义用户可选转换的接口,并且在 c
和a
:
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)
代码库的其余部分主要定义了几种不同的数据类型,用户可以插入到 c
的 Env
部分,一些数据类型可以作为结果 a
,以及存在用于保存一两个参数并且是 Base
或 Step
实例的数据类型的 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 c
与 c
中的其他 c
统一起来?>
(我也尝试将解析器转换为继续传递的样式,但是一旦我完成它,我就意识到我根本没有解决问题。)
还有更深层次的奥秘,我如何让 GHC 在值级别执行类型函数 Request
,以便我可以使 Request 中的 b -> a
由 a
指示a
的 Base
实例,或者向用户返回一条消息,让他们知道他们选择的 b
不是为他们指定的 b
定义的?
感觉就像我想要的是使用类型相等见证,但使用类型类而不是类型 c
,但我搜索了 GHC 的扩展丛,但没有找到允许这样做的东西。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)