繁体   English   中英

我们如何限制 Haskell 中的递归调用?

[英]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] -> atail :: [a] -> [a]或者被定义为变量,因为这些东西会遮蔽现有的绑定等功能。 这使得对代码进行推理变得更加困难,因为人们可能认为headtail指的是这些函数,而不是变量。

使用Control.Arrow.first (或Data.Bifunctor.firstarrow库随 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM