在F#中,我可以使用|
在模式匹配时对案例进行分组。例如,
let rec factorial n =
match n with
| 0 | 1 -> 1 // like in this line
| _ -> n * factorial (n - 1)
Haskell的语法是什么?
答案 0 :(得分:30)
对于不同的模式,无法共享相同的右侧。但是,您通常可以通过使用警卫而不是模式来解决这个问题,例如使用elem
。
foo x | x `elem` [A, C, G] = ...
| x `elem` [B, D, E] = ...
| otherwise = ...
答案 1 :(得分:10)
有警卫:
factorial n
| n < 2 = 1
| otherwise = n * (factorial (n - 1))
模式匹配:
factorial 0 = 1
factorial 1 = 1
factorial n = n * (factorial (n - 1))
答案 2 :(得分:8)
基于上述一些答案,您可以(至少现在)使用警卫在一行上执行多个案例:
case name of
x | elem x ["Bob","John","Joe"] -> putStrLn "ok!"
"Frank" -> putStrLn "not ok!"
_ -> putStrLn "bad input!"
所以,输入&#34; Bob&#34;,&#34; John&#34;或&#34; Joe&#34;会给你一个&#34; ok!&#34;,而&#34; Frank&#34;将是&#34;不行!&#34;,其他一切都将是&#34;糟糕的输入!&#34;
答案 3 :(得分:7)
我并不完全熟悉F#,但在Haskell中,case语句允许您将模式匹配,绑定变量绑定到表达式的各个部分。
case listExpr of
(x:y:_) -> x+y
[x] -> x
_ -> 0
在Haskell允许相同的理论案例中:
因此允许多个绑定
会有问题case listExpr of
(x:y:_) | [z] -> erm...which variables are bound? x and y? or z?
在极少数情况下,使用相同的绑定可以起作用:
unEither :: Either a a -> a
unEither val = case val of
Left v | Right v -> v
正如你给出的例子,如果你只匹配文字并且不绑定任何东西,它可以正常工作:
case expr of
1 | 0 -> foo
_ -> bar
<强>然而强>
据我所知,Haskell没有这样的语法。但是,正如其他人所提到的那样,它确实有警卫。
另请注意:
在case语句中使用|
在Haskell中提供不同的功能。 |之后的声明充当警卫。
case expr of
[x] | x < 2 -> 2
[x] -> 3
_ -> 4
因此,如果要将此类语法引入Haskell,则必须使用|
以外的其他语法。我建议使用,
(对于任何想要将其添加到Haskell规范中的人来说。)
unEither val = case val of
Left v, Right v -> v
这当前产生“输入,
上的解析错误”
答案 4 :(得分:3)
这是一个相当字面的翻译:
factorial n = case n of
0 -> sharedImpl
1 -> sharedImpl
n -> n * factorial (n - 1)
where
sharedImpl = 1
查看模式也可以为您提供字面翻译。
isZeroOrOne n = case n of
0 -> True
1 -> True
_ -> False
factorial1 n = case n of
(isZeroOrOne -> True) -> 1
n -> n * factorial (n - 1)
factorial2 n = case n of
(\n -> case n of { 0 -> True; 1 -> True; _ -> False }) -> 1
n -> n * factorial (n - 1)
并不是说这些比替代品更好。只是指出它们。