F# Fsharp:为函数传递N个参数

F# Fsharp:为函数传递N个参数,f#,F#,我试图创建一个函数,该函数接受可变数量的参数,但我似乎找不到任何可行的F#解决方案 如何将数量可变的参数传递给表达式函数?在F#中,具有不同签名(包括不同数量的参数)的函数被视为不同的类型。任何时候你想让一个函数接受一个可以是两种不同类型(甚至十几种不同类型)的参数,你都需要使用。以下是如何以编译和执行您试图执行的操作的方式编写代码: type Expression<'a> = | Double of ('a -> 'a -> 'a) | Triple o

我试图创建一个函数,该函数接受可变数量的参数,但我似乎找不到任何可行的F#解决方案

如何将数量可变的参数传递给表达式函数?

在F#中,具有不同签名(包括不同数量的参数)的函数被视为不同的类型。任何时候你想让一个函数接受一个可以是两种不同类型(甚至十几种不同类型)的参数,你都需要使用。以下是如何以编译和执行您试图执行的操作的方式编写代码:

type Expression<'a> =
    | Double of ('a -> 'a -> 'a)
    | Triple of ('a -> 'a -> 'a -> 'a)

let expression = fun a b -> a || b
let expressionTriple = fun a b c -> (a || b) && c

// This works because expression is a discriminated union
let truthTable expression =
    match expression with
    | Double f -> f true true
    | Triple f -> f true true false

truthTable (Double expression)
truthTable (Triple expressionTriple)
类型表达式“a->”a)
|三重('a->'a->'a->'a)
让表达式=乐趣a b->a | | b
让expressionTriple=fun a b c->(a | | b)和c
//这是因为表达是一种受歧视的结合
让真实的表达=
匹配表达式
|双f->f真-真
|三重f->f真-假
truthTable(双表达式)
truthTable(三重表达式Triple)
如果您想添加一个四参数版本,只需将('a->'a->'a->'a->'a->'a->'a->'a)大小写的
四元组添加到该区分的并集,依此类推


如果您对此有任何疑问,比如为什么我用泛型
'a
而不是
bool
,请随时提出后续问题。

您希望
truthTable 3表达式
做什么?truthTable 3表示我传入的谓词数量是,但是
expression
只接受2个参数,因此
expression true-false
通常是编译错误。另一个选项是重载,但我不会使用重载来建模任意真值表。有没有办法把它扩展到任意N个参数?我目前的解决方法是使用ParamArray,我从Github repo中看到,您正在处理99个问题集,这就是问题48。到目前为止,我看到的解决这个问题的唯一方法是将
表达式
变成一个接受列表的函数。例如,的问题陈述希望您定义一个函数
tablen
,该函数可以像
tablen 3(fun[a;b;c]->a&&(b|c)=a&&b|a&&c)
一样调用。您的
ParamArray
解决方案离这并不遥远。但一般来说,不,在F#中不能有一个包含N个任意参数的函数签名。正如您已经发现的,您可以使用数组或列表,它们作为单个参数传递。此限制的原因是,它会导致和的问题:如果您的函数允许多个参数,编译器如何知道您希望何时部分应用它?因此,为了允许咖喱,禁止使用多个参数。
let expression = (fun [a; b] -> a || b)
let expressionTriple = (fun [a; b; c] -> (a || b) && c)

let truthTable numPredicates expression =
   if numPredicates = 2 then
      expression [true; true]
   else
      expression [true; true; false]


truthTable 2 expression 
truthTable 3 expressionTriple 
let expression = (fun [a; b] -> a || b)
let expressionTriple = (fun [a; b; c] -> (a || b) && c)

let truthTable numPredicates expression =
   if numPredicates = 2 then
      expression [true; true]
   else
      expression [true; true; false]


truthTable 2 expression 
truthTable 3 expressionTriple