我有一个像这样的歧视联盟:
type A = |B | C of int*A
我必须像这样模式匹配(似乎需要括号):
match x with
| B -> printfn "B"
| C (i,a) -> printfn "%A, %A" i a
有没有办法像这样匹配类似活动模式的东西:
match x with
| B -> printfn "B"
| C i a -> printfn "%A, %A" i a
如果不是,为什么F#的设计使得与curried参数的匹配不起作用而反而迫使你使用元组?
编辑:这受到了F#列表的启发,您可以在其中使用h::t
而无需任何元组或其他类似内容。源代码如下:
type List<'T> =
| ([]) : 'T list
| (::) : Head: 'T * Tail: 'T list -> 'T list
答案 0 :(得分:2)
您的歧视联盟中的案例C
的值为元组类型(int * A)
。
模式匹配的(i,a)
部分不是参数,它将i
与int
部分匹配,a
与A
匹配一部分。
您可以与C x
同等匹配,而x
会保留(int * A)
的元组。
答案 1 :(得分:2)
我认为检查一个curried函数和一个活动模式的定义会让你清楚。
咖喱功能: 一个函数,它接受多个参数,但允许您一次传递一个参数,以便返回一个函数,该函数执行相同的操作,但只需要一个参数。示例:
let add a b = a + b
//val add : a:int -> b:int -> int
let add5 = add 5
//val add5 : (int -> int)
活动模式: 一种应用模式匹配的方法,其中匹配可以使用解析或其他复杂逻辑来完成。获取一个参数并返回解析结果。所以输入 - &gt;单一返回参数。
//Example taken from https://fsharpforfunandprofit.com/posts/convenience-active-patterns/
let (|Int|_|) str =
match System.Int32.TryParse(str) with
| (true,int) -> Some(int)
| _ -> None
val ( |Int|_| ) : str:string -> int option
由于曲线函数的整个要点是能够部分应用函数,因此该概念在应用于活动模式的结果时毫无意义。
换句话说,活动模式的结果不能“curry”,因为你只能curry函数,而活动模式的结果是不是函数的数据。在您的示例中,'C(i,a)'定义了Active Pattern案例的 return 类型,而不是函数调用。
答案 2 :(得分:2)
您不能将空格作为绑定模式之间的分隔符,因为联合情况和活动模式都不支持此。根据{{3}}:
的语法6.9.8评估联盟案例
Case(e1,…,en)
7.2.3活动模式
(|CaseName|) arg1 ... argn inp (|CaseName|_|) arg1 ... argn inp
因此,它必然是工会案件的一个重要论点;香蕉函数的n + 1个参数,其中n个参数是参数。只有最后一个参数才能绑定到模式。考虑:
TypeError: drop() takes at least 2 arguments (3 given)