Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Can';t将简单的python代码转换为haskell_Python_Haskell_Recursion - Fatal编程技术网

Can';t将简单的python代码转换为haskell

Can';t将简单的python代码转换为haskell,python,haskell,recursion,Python,Haskell,Recursion,我想把这个转换成Haskell def longest_path(edge, edges): remaining = list(edges) del remaining[remaining.index(edge)] possibles = [x for x in remaining if x[0] == edge[1]] maxchain = [] for c in possibles: l = longest_path(c, remain

我想把这个转换成Haskell

def longest_path(edge, edges):
    remaining = list(edges)
    del remaining[remaining.index(edge)]
    possibles = [x for x in remaining if x[0] == edge[1]]
    maxchain = []
    for c in possibles:
        l = longest_path(c, remaining)
        if len(l) > len(maxchain):
            maxchain = l
    return [edge] + maxchain
就我所知

deleteN :: Int -> [a] -> [a]
deleteN _ []     = []
deleteN i (x:xs)
   | i == 0    = xs
   | otherwise = x : deleteN (i-1) xs

longestPath edge edges = let
  remaining = deleteN (fromMaybe $ elemIndex edge edges) edges
  possibiles = [opt | opt <- remaining, (fst opt) == (snd edge)]
deleteN::Int->[a]->[a]
deleteN[]=[]
删除i(x:xs)
|i==0=xs
|否则=x:deleteN(i-1)xs
最长路径边=let
剩余=删除(可能来自$elemIndex边缘)边缘

可能=[opt | optpython代码并不是最好的…我不认为找到
edge
的索引然后
del
对其进行处理有什么意义…只需使用
edges.remove(edge)

同样,在Haskell中,您只需
过滤
边缘即可:

remaining = filter (/= edge) edges
现在,您的
for
循环正在跟踪迄今为止最好的结果。在Haskell中,这可以通过使用累加器参数的递归函数来完成。然而,这里的模式是一个
折叠

foldr f [] possibilities
其中:

f c maxchain = let l = longestPath c remaining
               in
                   if length l > length maxchain then l else maxchain
您可以修改
longestPath
,也可以返回路径的长度,避免调用
length


完整的代码如下所示:

longestPath edge edges = foldr f [] possibilities
  where
    remaining = filter (/= edge) edges
    possibilities = [opt | opt <- remaining, (fst opt) == (snd edge)]
    f c maxchain = if length l > length maxchain then l else maxchain
      where
        l = longestPath c remaining
longestPath edge=foldr f[]可能性
哪里
剩余=过滤器(/=边)边
可能性=[opt | opt length maxchain然后l else maxchain
哪里
l=剩余最长路径c

正如注释中所指出的,您可以使用
删除边
而不是
过滤器
来删除一个出现的
。但是,如果您处理的是标准图形,这应该无关紧要。

注意:这个答案是用识字Haskell编写的。将其另存为
*。lhs
,然后将其加载到in GHCi

导入数据.Ord(比较) >导入数据列表(删除,最大化) >类型Edge=(Int,Int)
让我们看看您的Python代码,并思考Haskell函数应该是什么样子:

def最长路径(边,边):
好的。我们从一条边和一列边开始。因此,我们应该用这种类型编写一个函数:

>最长路径::边缘->[Edge]->[Edge]
>最长路径边=
现在,我们在Python代码中做什么?显然,我们从边缘列表中删除了当前的
edge

剩余=列表(边)
del剩余[剩余索引(边)]
幸运的是,有一个函数可以删除列表中第一个出现的元素,即
delete

>让剩余=删除边
到目前为止还不错。现在,
possibles
只是具有正确端点的边的列表:

possibles=[x为x,如果x[0]==edge[1]]
这也很简单:

>possibles=filter(边`connectedTo`)边
然后我们寻找所有可能边的最长链。

maxchain=[]
对于c,在可能的情况下:
l=最长路径(c,剩余)
如果len(l)>len(maxchain):
maxchain=l
由于我们无法在Haskell中修改
maxchain
,因此让我们创建所有这些中间路径:

>路径=[]:映射(\e->最长路径e剩余)可能
这是递归发生的地方。对于可能边中的每个
,我们创建该边和其余边的
最长路径

大部分的
for
循环可以表示为
映射和下面的折叠。我们将使用的折叠是
maximumBy
,其中我们根据列表的长度与
比较长度来比较列表:

>在边缘中:最大长度(比较长度)路径
我们使用了一个小助手,
connectedTo
。但这很简单:

>连接到::边缘->边缘->布尔
>连接到(u,b)(x,u)=b==x
一次完成所有代码:

导入数据列表(删除,最大化)
导入数据。Ord(比较)
类型Edge=(Int,Int)
最长路径::边缘->[Edge]->[Edge]
最长路径边=
让剩余=删除边
可能=筛选(边“连接到”)边
路径=[]:映射(\e->最长路径e剩余)可能
在边中:最大(比较长度)路径
连接到::边缘->边缘->布尔
连接到(u,b)(x,u)=b==x

您不需要显式循环或递归。“为列表中的每个元素计算一些东西”。有一个内置函数,名为
map
“查看列表并根据以前的值和当前列表元素更新值"。另一个内置项foldr。@n.m.
for
不是一个
映射,因为它在循环过程中跟踪最好的
maxchain
。它更像是一个
折叠
。呃,
剩余=删除边
与Python/OPs代码中的行为相同。并行边可能被允许,因此不应该被删除@Zeta注意到了这一点,但这可能并不重要。运行时可能会略有不同,但是的,我想不会有那么多平行边。这几乎可以工作,但它抛出了一个异常:List.maximumBy:empty List*它打印路径上的前几条边,但随后无法给出exception@D.B.Cooper呃,对不起,我忘了pty案例。