在Haskell中使用保护比使用递归函数的模式更好吗?

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)

Dan*_*ton 9

我的一般经验法则是:

  • 当守卫是一个简单的==检查时使用模式匹配.

通过递归,您通常会检查基本情况.因此,如果您的基本案例是一个简单的==检查,那么使用模式匹配.

所以我通常这样做:

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语句.