我有以下功能:
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]
为空,即使在某些时候失败也是如此。
知道为什么会这样吗??
谢谢!
答案 0 :(得分:2)
使用模式匹配和case语句编写函数更有意义,这避免了对fromMaybe
,head
和tail
的所有调用,这些调用当前使您的问题变得混乱代码。
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
由于x
和z
在递归中是固定的,因此使用辅助函数编写它也是有意义的
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)
现在简化了这个功能,找出错误的地方应该更加容易。