2

我正在自学在 Haskell 中编程,并且正在开发一个查找功能。它的作用是接受两个字符串,例如"hello"and "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,这需要一些用户输入的冗余数据。searchsearch1

我的问题是,在 Haskell 中创建一个“插入”冗余数据的函数是一种好习惯吗?还是我应该做一些不同的事情?

4

1 回答 1

7

是的,这是一个很好的做法。但是,如果第二个函数本身没有用,而只能作为另一个函数的工作人员,则最好将第二个函数设置为第一个函数。

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

对于您的示例,具有本地工作人员的功能可能看起来像

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

我已经消除了在递归调用中从未改变过的工人的一个论点。此外,使工人成为本地人消除了检查空的需要needle

于 2012-05-15T20:29:35.477 回答