表达式中“或”的Haskell语法

时间:2011-09-29 21:19:21

标签: haskell f# functional-programming

在F#中,我可以使用|在模式匹配时对案例进行分组。例如,

let rec factorial n = 
  match n with
  | 0 | 1 -> 1                 // like in this line
  | _ -> n * factorial (n - 1)

Haskell的语法是什么?

5 个答案:

答案 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)

并不是说这些比替代品更好。只是指出它们。