我有一个深层嵌套的记录,我正在尝试从数据库重建它。例如,
A
包含许多B
记录。 B
记录有很多 C
记录。 C
有很多 D
。我有函数来查询每种类型的对象的子对象(下面的f0
、f1
和f2
)。
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
这样的东西应该可以工作(未经测试):
pairFun f = id &&& f
foo = (fmap . map) ((fmap . map) (pairFun f2) . pairFun f1) . pairFun f0
编辑:顺便说一句,思考这个问题的一种方法是使用 conal 的语义编辑器组合器模型 - http://conal.net/blog/posts/semantic-editor-combinators