[英]Haskell: encoding a generic schema
首先,有一些动机:我想从多个地方进行配置-命令行参数,可能是配置文件,以及其他一些服务。 我对这些来源的格式没有特别的关心。 我想做的是描述该配置的架构,并根据需要让可插拔源为该配置生成解析器/编写器。 模式还应该对诸如帮助文本,可能的完成选项等进行编码。
这是我到目前为止所拥有的基础:
data Name =
LongName String
| ShortName Char
data OptionDefault a = OptionDefault (Maybe a) (Maybe (a -> String))
data OptionDescr = OptionDescr {
odNames :: [Name]
, odSummary :: String
, odDetail :: String
}
data Option a = Option {
oReader :: Monad m => String -> m a
, oDefault :: OptionDefault a
, oDescr :: OptionDescr
}
我不知道该怎么做是由这些组成的 -例如,将配置节定义为类型为Option Foo
, Option Bar
和Option Baz
三个选项以及函数f :: Foo -> Bar -> Baz -> FBBSection
。 这与构成解析器是一个不同的问题, 解析器应在以后由特定格式的生成器来完成。
我唯一能想到的就是将选项存储为某种HList,并为f
强制进行某种折叠构成-还有其他想法吗?
如果您有Option的适用实例:
foo :: Option Foo
bar :: Option Bar
baz :: Option Baz
f :: Foo -> Bar -> Baz -> FBBSection
fbbSection :: Option FBBSection
fbbSection = f <$> foo <*> bar <*> baz
现在,麻烦在于编写Applicative实例。 首先,您需要一个Functor实例,但您实际上不能提供一个实例: OptionDefault
是不变函子,因为它的类型参数a
出现在Maybe a
正位置和Maybe a
的负位置Maybe (a -> String)
OptionDefault
Maybe (a -> String)
。 Haskell中的Functor类型类仅适用于协变函子。
您可能需要重新检查数据以查看是否可以使其协变。 尽管我不确定,但Applicative
可能有一个不变的东西。 我不确定curry如何用于同构,如果有的话,从分类的角度来看, Applicative
实际上实际上更依赖于currying。
完成所有这些操作后,您需要定义Applicative如何组合OptionDescr值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.