如何解决将免费的 monad DSL 映射到外部
(添加了 Haskell 和 OCaml 标签,因为这在那些世界中可能更常见)
我采用了一个简单的 API(searchCriteria 和 runReport)并遵循了免费的 monad 配方并为其创建了一个 DSL。
例如
(Haskeller 认为“做”表示法)
let program = dsl {
let! searchCriteria = search { channel = Some "Foo" }
do! runReport ("MyReport",searchCriteria)
}
并编写了相应的解释器,这样我就可以分别编写“程序”然后“解释”它们。
而且效果很好....按照配方...弹出一个 DSL。
我真的想将它序列化为 JSON 或类似的东西,所以我需要定义一个正式的语法来捕获这种 monadic 语法......所以像这样?
type VarName = string
type ChannelName = string
type Report = string
type MExpression =
| SearchDay of ChannelName
| RunReport of Report * Expression
and Expression =
| ValueOf of VarName
type ProgramLine =
| Let of VarName * MExpression
| Do of MExpression
其中 MExpression 是 monad 中的表达式,而 ValueOf 只是对已分配变量的评估。
然后我可以这样表达我的程序
type ExternalDSL = ProgramLine list
let foo : ExternalDSL =
[ Let ("days",SearchDay "Foo")
Do (RunReport ("MyReport",ValueOf "days")) ]
并将上面的一些转换写入我的免费 monad 版本(尽管它变成了一个免费的 monad,有效地将变量映射到它们作为对象的值......你必须将其丢弃),然后执行它。
我的语法(MExpression 等)感觉很不自然,是否有“现成的”方法可以解决这个问题?显然,对于 API 上的每个方法,我都会为 DExpression 添加一个新值。
例如,也许我可以通过添加类似的东西来添加嵌套这些“程序”的能力
| Nest of (ProgramLine list * VarName)
其中 VarName 是要返回的变量的名称(这似乎是错误的!)
所以我觉得这种语法编码不正确,以前肯定有人这样做过吗?在一些标准的 CS 教科书中?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。