mac*_*ian 8 recursion layout haskell pattern-matching guard
我只是想知道我在Haskell中设置的递归函数.使用保护通常比递归函数的模式更好吗?
我只是不确定最佳布局是什么,但我知道在定义这样的函数时模式更好:
units :: Int -> String
units 0 = "zero"
units 1 = "one"
Run Code Online (Sandbox Code Playgroud)
更喜欢
units n
| n == 0 = "zero"
| n == 1 = "one"
Run Code Online (Sandbox Code Playgroud)
我只是不确定在递归方面是否相同或不同.
只是不太确定术语:我使用的是这样的东西:
f y [] = []
f y (x:xs)
| y == 0 = ......
| otherwise = ......
Run Code Online (Sandbox Code Playgroud)
或者这会更好吗?
f y [] = []
f 0 (x:xs) =
f y (x:xs) =
Run Code Online (Sandbox Code Playgroud)
我的一般经验法则是:
==检查时使用模式匹配.通过递归,您通常会检查基本情况.因此,如果您的基本案例是一个简单的==检查,那么使用模式匹配.
所以我通常这样做:
map f [] = []
map f (x:xs) = f x : map f xs
Run Code Online (Sandbox Code Playgroud)
而不是这(null只是检查列表是否为空.基本上是这样== []):
map f xs | null xs = []
| otherwise = f (head xs) : map f (tail xs)
Run Code Online (Sandbox Code Playgroud)
模式匹配是为了让你的生活更轻松,imho,所以最后你应该做对你有意义的事情.如果您与团队合作,那么请对团队做有意义的事情.
[更新]
对于你的特殊情况,我会做这样的事情:
f _ [] = []
f 0 _ = ...
f y (x:xs) = ...
Run Code Online (Sandbox Code Playgroud)
模式匹配,如警卫,从上到下,在与输入匹配的第一个定义处停止.我使用下划线符号表示对于第一个模式匹配,我不关心y参数是什么,对于第二个模式匹配,我不关心列表参数是什么(尽管如果你使用列表在那个计算中,那么你不应该使用下划线).由于它仍然是相当简单==的检查,我个人坚持使用模式匹配.
但我认为这是个人偏好的问题; 你的代码是完全可读和正确的.如果我没有弄错的话,在编译代码时,守护和模式匹配最终都会变成case语句.