假设有一个图表和一些功能集如:
create-node :: Graph -> (Graph, Node)
split-node :: Graph -> Node -> (Graph, Node, Node)
我想创建那些不希望Graph
作为参数的函数的版本,主要是为了方便(最好不要使用monad,所以我不需要在monad中包装每个图形操作代码片段块)。那么这个怎么样:
create-node :: (Graph -> (Graph, Node))
split-node :: (Graph -> Node) -> ((Graph -> Node), (Graph -> Node))
或更一般地说:
fun :: (Graph -> Argument) -> ... -> (Graph -> Result)
然后我就可以使用(Graph -> ...)
值,就好像它们是普通节点一样。最后,要从(Graph -> ...)
值中获取实际图形,只需将其应用于空图形。这是一种合理的方法吗?
答案 0 :(得分:5)
好的,所以
create-node :: (Graph -> (Graph, Node))
是状态monad,只是没有花哨的newtype(以及翻转的返回值)。所以我没有看到在这里不使用State
的优势。毕竟,让我使用状态Monad编写相当干净的代码:
reverseEdgesM :: State Graph ()
reverseEdgesM = do --...
每当我使用runState
和朋友运行一些纯代码时,就会弹出它:
reverseEdges :: Graph -> Graph
reverseEdges = execState reverseEdgesM
如果您确实希望推进功能创意,可能需要查看difference lists以了解如何使用简单列表。
此外,如果您只是要实现一些算法,您可能需要查看现有的功能图数据结构库(如fgl),而不是自己编写。如果您想了解理论,请查看Erwig's paper on inductive graphs。