被歧视的联盟中的咖喱论据

时间:2016-08-26 15:12:38

标签: f# discriminated-union active-pattern

我有一个像这样的歧视联盟:

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

3 个答案:

答案 0 :(得分:2)

您的歧视联盟中的案例C的值为元组类型(int * A)

模式匹配的(i,a)部分不是参数,它将iint部分匹配,aA匹配一部分。

您可以与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)