我应该创建一个函数来将数据输入另一个函数吗?

时间:2012-05-15 20:20:39

标签: haskell recursion

我正在教自己在Haskell中编程,我正在研究一个find函数。它的作用是需要两个字符串,例如"hello""he",并计算"he""hello"出现的次数。

find函数需要跟踪几个事情,例如在列表中找到的单词的次数,不需要在函数的开头输入。因此,我将该功能分解为两个较小的功能:一个用户最初输入数据,然后将数据导向第二个执行工作的功能。

这是我的代码:

search :: (Eq a) => [a] -> [a] -> Integer
search [] _ = 0
search _ [] = 0
search x y = search1 x y y 0

search1 :: (Eq a) => [a] -> [a] -> [a] -> Integer -> Integer
search1 _ _ [] n = n
search1 x [] z n = search1 x z z (n+1)
search1 [] _ _ n = n
search1 (x:xs) (y:ys) z n
  | x == y = search1 xs ys z n
  | otherwise = search1 xs (y:ys) z n

在其中,我创建函数search1以“插入”,而不是用函数search开始,这需要一些冗余供用户输入的函数。用户的数据search1

我的问题是,创建一个“插入”冗余数据的功能是Haskell的一个好习惯吗?或者我应该做些不同的事情?

1 个答案:

答案 0 :(得分:7)

是的,这是一种很好的做法。但是,通常最好将第二个函数设置为第一个函数,如果它本身没有用,并且仅作为另一个函数的工作者。

如果你在包装器的本地创建一个worker,你可以在worker的主体中引用包装器的参数,而不将它们作为参数传递给worker,这通常有助于提高性能。

对于您的示例,本地工作者的函数可能看起来像

search :: (Eq a) => [a] -> [a] -> Integer
search [] _ = 0
search _ [] = 0
search hay needle = search1 hay needle 0
  where
    search1 x [] n = search1 x needle (n+1)
    search1 [] _ n = n
    search1 (x:xs) (y:ys) n
      | x == y = search1 xs ys n
      | otherwise = search1 xs (y:ys) n

我已经删除了一个在递归调用中从未改变的worker的一个参数。此外,使本地工作人员无需检查空needle