我正在教自己在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
Run Code Online (Sandbox Code Playgroud)
在search1其中,我创建了为用户search"插入"数据的功能,而不是用户开始使用需要一些冗余供用户输入的功能search1.
我的问题是,创建一个"插入"冗余数据的功能是Haskell的一个好习惯吗?或者我应该做些不同的事情?
是的,这是一个很好的做法.但是,通常最好将第二个函数设置为第一个函数,如果它本身没有用,并且只作为另一个函数的工作者.
如果在包装器的本地创建一个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
Run Code Online (Sandbox Code Playgroud)
我已经消除了一个在递归调用中从未改变的工人的一个参数.此外,使工作人员本地消除了检查空的需要needle.
| 归档时间: |
|
| 查看次数: |
141 次 |
| 最近记录: |