[英]Haskell: encoding a generic schema
To begin with, some motivation: I want to take configuration from multiple places - command line arguments, possibly config files, some other service. 首先,有一些动机:我想从多个地方进行配置-命令行参数,可能是配置文件,以及其他一些服务。 I don't have any particular care for the format of these sources.
我对这些来源的格式没有特别的关心。 What I would like to do is describe a schema for that configuration and have pluggable sources generate parsers/writers for that config as necessary.
我想做的是描述该配置的架构,并根据需要让可插拔源为该配置生成解析器/编写器。 The schema should also encode things such as help text, possibly completion options, etc.
模式还应该对诸如帮助文本,可能的完成选项等进行编码。
Here's the basis of what I have so far: 这是我到目前为止所拥有的基础:
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
}
The thing I'm not sure how to do is compose these - eg to define a config section as being, say, three options of types Option Foo
, Option Bar
and Option Baz
as well as a function f :: Foo -> Bar -> Baz -> FBBSection
. 我不知道该怎么做是由这些组成的 -例如,将配置节定义为类型为
Option Foo
, Option Bar
和Option Baz
三个选项以及函数f :: Foo -> Bar -> Baz -> FBBSection
。 This is a different question to composing the Parsers , which should be done at a later date by a generator for the specific format. 这与构成解析器是一个不同的问题, 解析器应在以后由特定格式的生成器来完成。
The only thing I can think of is to store the options as some kind of HList, and force some kind of fold composition for f
- any other ideas? 我唯一能想到的就是将选项存储为某种HList,并为
f
强制进行某种折叠构成-还有其他想法吗?
If you have an Applicative instance for Option: 如果您有Option的适用实例:
foo :: Option Foo
bar :: Option Bar
baz :: Option Baz
f :: Foo -> Bar -> Baz -> FBBSection
fbbSection :: Option FBBSection
fbbSection = f <$> foo <*> bar <*> baz
Now, the trouble is in writing the Applicative instance. 现在,麻烦在于编写Applicative实例。 First of all, you need a Functor instance, but you can't really provide one:
OptionDefault
is an invariant functor because its type parameter a
occurs in both a positive position Maybe a
and in a negative position Maybe (a -> String)
. 首先,您需要一个Functor实例,但您实际上不能提供一个实例:
OptionDefault
是不变函子,因为它的类型参数a
出现在Maybe a
正位置和Maybe a
的负位置Maybe (a -> String)
OptionDefault
Maybe (a -> String)
。 The Functor typeclass in Haskell is only for covariant functors. Haskell中的Functor类型类仅适用于协变函子。
You might re-examine your data to see if you can make it covariant. 您可能需要重新检查数据以查看是否可以使其协变。 There might be an equivalent for
Applicative
that is invariant though I'm not sure; 尽管我不确定,但
Applicative
可能有一个不变的东西。 I'm not sure how currying works for isomorphisms, if it does at all, and Applicative
is actually rather dependent on currying, from a categorical perspective. 我不确定curry如何用于同构,如果有的话,从分类的角度来看,
Applicative
实际上实际上更依赖于currying。
After you got though all of that, you'd need to define how your Applicative combined OptionDescr values. 完成所有这些操作后,您需要定义Applicative如何组合OptionDescr值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.