使用箭头生成深层嵌套记录

时间:2013-02-05 19:00:23

标签: haskell arrows

我有一个深度嵌套的记录,我试图从数据库重建。例如,A包含许多B条记录。 B条记录包含许多C条记录。 C有很多D个。我有函数来查询每种类型对象的子项(下面有f0f1f2)。

f0 :: A -> [B]
f1 :: B -> [C]
f2 :: C -> [D]

我正在寻找一种实现f3的优雅方式。

f3 :: A -> (A, [(B, [(C, [D])])])

我在Arrows上读过一些内容,感觉它们可能非常适合。但是,当我尝试将它们组合在一起时,我一直在遇到障碍。

我从这样的事情开始:

f4 :: A -> (A, [B])
f4 = id &&& f0

让我到了第一级。但是,我无法找到将其链接到另一个箭头的方法,该箭头将映射[B],返回[(B, [C])]并将其用作原始元组的第二个元素。

我对Haskell有点新鲜,所以如果我需要包含任何其他信息,请告诉我。

谢谢!

更新

稍微修改sclv的答案,我现在有

data A = A
data B = B
data C = C
data D = D

f0 :: A -> [B]
f0 = undefined

f1 :: B -> [C]
f1  = undefined

f2 :: C -> [D]
f2 = undefined

pairFun f = id &&& f

foo :: A -> (A, [(B, [C])])
foo = fmap (map (pairFun f1)) . pairFun f0

我仍然无法理解如何组合最后一个函数(f2)。

最终更新

感谢sclv,事实证明这可以这样做:

foo = (fmap . map) ((fmap . map) (pairFun f2) . pairFun f1) . pairFun f0

1 个答案:

答案 0 :(得分:3)

这样的事情应该有效(未经测试):

pairFun f = id &&& f

foo = (fmap . map) ((fmap . map) (pairFun f2) . pairFun f1) . pairFun f0

编辑:顺便说一句,考虑这个问题的一种方法是使用conal的语义编辑器组合模型 - http://conal.net/blog/posts/semantic-editor-combinators