【发布时间】:2013-10-06 18:47:00
【问题描述】:
我需要使用 Haskell 在列表上生成传递闭包。
到目前为止,我得到了这个:
import Data.List
qq [] = []
qq [x] = [x]
qq x = vv (sort x)
vv (x:xs) = [x] ++ (member [x] [xs]) ++ (qq xs)
member x [y] = [(x1, y2) | (x1, x2) <- x, (y1, y2) <- qq (y), x2 == y1]
输出 1:
*Main> qq [(1,2),(2,3),(3,4)]
[(1,2),(1,3),(1,4),(2,3),(2,4),(3,4)]
输出 2:
*Main> qq [(1,2),(2,3),(3,1)]
[(1,2),(1,3),(1,1),(2,3),(2,1),(3,1)]
问题在于第二个输出。它不会在新生成的列表上检查额外的传递闭包,而是返回结果。
为了原型 haskell 代码,我使用了这个 Python 代码:
def transitive_closure(angel):
closure = set(angel)
while True:
new_relations = set((x,w) for x,y in closure for q,w in closure if q == y)
closure_until_now = closure | new_relations
if closure_until_now == closure:
break
closure = closure_until_now
return closure
print transitive_closure([(1,2),(2,3),(3,1)])
输出:
set([(1, 2), (3, 2), (1, 3), (3, 3), (3, 1), (2, 1), (2, 3), (2, 2), (1, 1)])
这是我在 Haskell 函数中需要的正确输出。
如何在我的 Haskell 代码中做同样的事情? (我需要将 if 语句从 Python 代码重新创建为 Haskell 代码)
【问题讨论】:
-
为什么你在 Python 中使用描述性名称,而在 Haskell 中使用神秘的速记?不管多么琐碎,类型签名也是一个好主意。
-
@leftaroundabout,我知道这是不好的做法,但我会在弄清楚这一点后更改变量/函数名称和类型签名。希望阅读这段代码不会太难。
标签: haskell transitive-closure