如何在参数级别上使用匹配,是否可能?逆天?

时间:2014-09-23 11:26:33

标签: f# pattern-guards

例如

let When true d = d
let foo = () |> When false

所以我有副作用,我不喜欢,因为它是错误的:MatchFailureException

我知道我可以在这里产生良好的副作用:let foo = if false then ()

但警告Incomplete pattern matches on this expression.告诉我,我可以添加我需要的东西。我只是不知道怎么可能?为什么我甚至可以使用值作为参数呢?

btw:我知道我可以写When b d = if b then d else (),但问题更为笼统。

在haskell中添加了解释

    let wh :: Bool -> IO () -> IO ()
        wh True f = f
        wh False f = return ()

2 个答案:

答案 0 :(得分:4)

当你写下这样的东西时:

let When true d = d

您告诉F#创建一个带有两个参数的函数,并且您将两个参数分别与模式trued匹配。 true模式不完整,并且当输入不是true值时失败。 d模式是变量绑定,它总是成功。

您可以在函数声明的参数中使用不完整的模式这一事实并不是特别有用(但我想您可以使用编译器无法验证的更复杂的模式)。

不完整的模式实际上只有在您使用match或使用function时才有意义。 function关键字为您提供了类似其他语言的警卫 - 但它只适用于采用单个参数的函数。如果您更改When以接受元组,则可以写:

let When = function
  | true, f -> f()
  | false, _ -> ()

或者,您可以颠倒参数的顺序(并使用currying),如Vesa.A.J.K的答案。

答案 1 :(得分:2)

这是允许的事实更多的是规范的一个怪癖,并且真的是你可以做的事情,如

let (a,b) = 1,2

您的问题不是特别清楚,但我认为您正在寻找类似

的内容
let 1 |2 = 1

基本上语法与匹配后的语法相同,除了您不需要第一个|

旁注,这允许我在一段时间内编写的最疯狂的F#代码:

let 1 = 2

这将编译(带警告)但在运行时失败。