定义Haskell函数的经典方法是
f1 :: String -> Int
f1 ('-' : cs) -> f1 cs + 1
f1 _ = 0
Run Code Online (Sandbox Code Playgroud)
我有点不满意在每一行写函数名.现在我通常用以下方式编写,使用模式保护扩展并认为它更易读和修改友好:
f2 :: String -> Int
f2 s
| '-' : cs <- s = f2 cs + 1
| otherwise = 0
Run Code Online (Sandbox Code Playgroud)
你认为第二个例子更具可读性,可修改性和优雅性吗?生成代码怎么样?(还没有时间看到脱落的输出,对不起!).什么是利弊?我唯一看到的是扩展用法.
好吧,你总是可以像这样写:
f3 :: String -> Int
f3 s = case s of
('-' : cs) -> f3 cs + 1
_ -> 0
Run Code Online (Sandbox Code Playgroud)
这意味着与f1版本相同.如果该函数具有冗长或难以阅读的名称,并且您希望与大量模式匹配,则这可能是一种改进.对于您的示例,我将使用传统语法.
f2这样你的版本没有任何问题,但它似乎是一种轻微无聊的语法GHC扩展的使用,这种扩展并不常见,以至于每个人都会熟悉它.对于个人代码而言,这不是什么大不了的事,但我会坚持使用case你期望别人阅读的任何内容.
我喜欢在函数模式匹配时编写函数名称,如您的情况所示.我发现它更具可读性.
当我在函数参数上有一些条件时,我更喜欢使用防护,这有助于避免if else,如果我要遵循第一个模式,我将不得不使用.
所以回答你的问题
Do you think that second example is more readable, modifiable and elegant?
Run Code Online (Sandbox Code Playgroud)
不,我更喜欢第一个简单易读的.但或多或少取决于你的个人品味.
What about generated code?
Run Code Online (Sandbox Code Playgroud)
我不认为生成的代码会有任何区别.两者都只是模式匹配.
What are cons?
Run Code Online (Sandbox Code Playgroud)
好的模板对模式匹配很有用,而不是使用let或更干净的东西.
addLookup env var1 var2
| Just val1 <- lookup env var1
, Just val2 <- lookup env var2
= val1 + val2
Run Code Online (Sandbox Code Playgroud)
那么con是当然你需要使用扩展,而且它不是Haskell98(你可能不会考虑很多con)
另一方面,对于函数参数的简单模式匹配,我将使用第一种方法,它简单易读.