[英]How can we limit recursive calls in Haskell?
我的代码有问题,如下所示:
import Data.List
splitat _ [] = ([],[])
splitat element (head:tail)
| element == head = ([],(head:tail))
| otherwise = ([head]++fst(splitat element tail), snd(splitat element tail))
它在“元素”处拆分列表,然后将左右子列表组合成一个元组。 然而,在第三行,'splitat element tail' 命令被调用两次,一次通过'fst',一次通过'snd'。 有没有办法只评估这个术语 1 次以保持递归树的狭窄?
提前致谢。
是的。 您可以使用let
表达式或where
子句。 例如:
splitat :: Eq a => a -> [a] -> ([a], [a])
splitat _ [] = ([],[])
splitat x' xa@(x:xs) | x == x' = ([], xa)
| otherwise = (x:ys1, ys2)
where (ys1, ys2) = splitat x' xs
注:请不要使用
head :: [a] -> a
或tail :: [a] -> [a]
或者被定义为变量,因为这些东西会遮蔽现有的绑定等功能。 这使得对代码进行推理变得更加困难,因为人们可能认为head
和tail
指的是这些函数,而不是变量。
使用Control.Arrow.first
(或Data.Bifunctor.first
; arrow
库随 GHC 一起提供,而我不记得您是否需要先安装bifunctor
):
splitat _ [] = ([],[])
splitAt e lst@(h:t) | e == h = ([], lst)
| otherwise = first (h:) (splitAt e t)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.