【发布时间】:2016-07-07 14:53:16
【问题描述】:
用字母替换字段名称,我有这样的情况:
data Foo = Foo { a :: Maybe ...
, b :: [...]
, c :: Maybe ...
, ... for a lot more fields ...
} deriving (Show, Eq, Ord)
instance Writer Foo where
write x = maybeWrite a ++
listWrite b ++
maybeWrite c ++
... for a lot more fields ...
parser = permute (Foo
<$?> (Nothing, Just `liftM` aParser)
<|?> ([], bParser)
<|?> (Nothing, Just `liftM` cParser)
... for a lot more fields ...
-- this is particularly hideous
foldl1 merge [foo1, foo2, ...]
merge (Foo a b c ...seriously a lot more...)
(Foo a' b' c' ...) =
Foo (max a a') (b ++ b') (max c c') ...
什么技术可以让我更好地管理这种增长?
在一个完美的世界中,a、b 和 c 都是相同的类型,所以我可以将它们放在一个列表中,但它们可以是许多不同的类型。我对无需大量模式即可折叠记录的任何方式特别感兴趣。
我正在使用这个大记录来保存permutation parsing the vCard format 产生的不同类型。
更新
我已经实现了下面建议的generics 和foldl 方法。它们都有效,并且都将three large field lists 减为1。
【问题讨论】:
-
记录字段是否需要命名(
Foo可以是记录以外的其他名称)吗? -
这种 XY 问题的味道。也许解决方案是根本没有那种
Foo,但要做出这种判断,我们必须获得有关Foo必须解决的问题的信息。 -
似乎是数据类型泛型编程的一个用例,可能使用像“generics-sop”这样的泛型库。
-
@Bakuriu - 好点。我添加了一条关于我要解决的问题的注释。基本上,记录已经到位,可以收集permutation parsing the vCard format 产生的不同类型。在我链接到你的代码中,你可以看到它是如何变得笨拙的。我不知道我能确定类型只会是列表和 Maybes - 这是一个早期而粗略的 impl - 但也许可以以某种方式利用只有两种类型的事实......