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