仅修改一次函数的参数

时间:2017-10-01 10:27:20

标签: haskell

我几天前开始使用Haskell。 我有以下代码片段(递归函数):

totaltime t [x] = 0
totaltime t route = tbd + totaltime (t+tbd) (tail(route))
    where tbd = timebetweendepartures (fst(route!!0)) (fst(route!!1)) t (snd(route!!1))

“route”是一个元组列表,例如:[(3,1),(1,2),(5,2),(2,1)]

我正在尝试做的是在函数开始执行它应该执行的操作之前将(0,0)添加到路径。

因此,如果参数路由作为[(3,1),(1,2),(5,2),(2,1)]传递,那么函数应该接收它为[(0,0), (3,1),(1,2),(5,2),(2,1)]

我可以做totaltime t ((0,0):route),但由于该函数是递归的,因此无法按预期工作。

非常感谢您的想法!

2 个答案:

答案 0 :(得分:7)

简短回答:您可以将函数totaltime置于where子句范围内,并公开另一个以(0,0)为前缀的函数:

totaltime t l = tt t ((0,0):l)
where tt t [x] = 0
      tt t route = tbd + tt (t+tbd) (tail(route))
          where tbd = timebetweendepartures (fst(route!!0)) (fst(route!!1)) t (snd(route!!1))

但话虽如此,代码非常不优雅,可能不安全:

  • 您没有为空列表定义案例;
  • 用于空列表的情况是第二个子句,您调用!!0!!1这些函数不是 total

此外,您调用fstsnd并不是很优雅。我们可以在条款的头部引入模式,通常使它更优雅,更容易理解。因此,我们可以将tt函数重写为:

tt t [] = ... # create a case for the empty list
tt t [x] = 0
tt t ((x0,_):xys@((x1,y1):_)) = tbd + tt (t+tbd) xys
    where tbd = timebetweendepartures x0 x1 t y1

现在我们可以使用它:

totaltime t l = tt t ((0,0):l)
    where tt t [] = ... # create a case for the empty list
          tt t [x] = 0
          tt t ((x0,_):xys@((x1,y1):_)) = tbd + tt (t+tbd) xys
              where tbd = timebetweendepartures x0 x1 t y1

当然在这种情况下,永远不可能处理空列表,因为totaltime预先(0,0)我们保证初始调用是一个至少有一个元素的调用,而我们在直接尾部执行递归,这意味着列表一次减少一个。

然而,我们仍然可以通过使用三个句子来改进功能:t变量;列表的头部,列表的尾部,并将其重写为:

totaltime t = tt t (0,0)
    where tt _ _ [] = 0
          tt t (x0,_) (xyh@(x1,y1):xyt) = tbd + tt (t+tbd) xyh xyt
              where tbd = timebetweendepartures x0 x1 t y1

现在代码在语法上是完全的,而且它可以提高效率(因为我们避免解压缩列表的某些部分两次。

我们仍然可以改进代码。请注意,我们只使用列表头部的第一个元素(我们不使用y0变量)。所以我们可以省略打包和解压缩并将其重写为:

totaltime t = tt t 0
    where tt _ _ [] = 0
          tt t x0 ((x1,y1):xyt) = tbd + tt (t+tbd) x1 xyt
              where tbd = timebetweendepartures x0 x1 t y1

现在我们可以节省解包元组,并且更清楚我们的工作。

答案 1 :(得分:4)

您可以将该功能包装到"入口点"执行外部接收参数预处理的函数:

 totaltime t route =
   totaltime' t ((0,0):route)
   where
      totaltime' t [x] = 0
      totaltime' t route = .....