函数递归时不应该

时间:2013-12-18 23:29:16

标签: haskell recursion

我有以下功能:

followConnections :: [Connection]->Crib->Stecker->Offsets->Maybe Stecker
followConnections [] _ y _ = Just (y)
followConnections w x y z
    | fC /= Nothing = trace("Follow Connections recursing") followConnections (tail w) x (fromMaybe(fC)) z
    | fC == Nothing = trace("Follow connections fail! for " ++ show y) Nothing
    where
    fC = followConnection (head w) x y z

从技术上讲,如果[Connection]的当前元素不会导致followConnection返回Nothing,则该函数应该递归,否则返回Nothing。 但是,通过跟踪函数,我看到它会递归,直到[Connection]为空,即使在某些时候失败也是如此。

知道为什么会这样吗??

谢谢!

1 个答案:

答案 0 :(得分:2)

使用模式匹配和case语句编写函数更有意义,这避免了对fromMaybeheadtail的所有调用,这些调用当前使您的问题变得混乱代码。

followConnections :: [Connection] -> Crib -> Stecker -> Offsets -> Maybe Stecker
followConnections []     _ y _ = Just y
followConnections (w:ws) x y z = case fC of
    Nothing -> trace ("Fail! for " ++ show y) $ Nothing
    Just y' -> trace ("Recursing")            $ followConnections ws x y' z
  where
    fC = followConnection w x y z

由于xz在递归中是固定的,因此使用辅助函数编写它也是有意义的

followConnections ws x y z = go ws y
  where
    go []     y = Just y
    go (w:ws) y = case fc of
        Nothing -> trace ("Fail for" ++ show y) $ Nothing
        Just y' -> trace ("Recursing")          $ go ws y'
      where
        fc = followConnection w x y z

最后,您可以使用maybe中的Data.Maybe函数来删除case语句,从而进一步简化代码。

followConnections ws x y z = go ws y
  where
    go []     y = Just y
    go (w:ws) y = maybe Nothing (go ws) (followConnection w x y z)

现在简化了这个功能,找出错误的地方应该更加容易。