F# 在部分应用程序上使用序列

F# 在部分应用程序上使用序列,f#,F#,我有一个我想部分应用于函数的值序列: let f a b c d e= a+b+c+d+e let items = [1,2,3,4,5] let result = applyPartially f items Assert.Equal(15, result) 我负责applyPartially函数。我尝试过编写如下递归函数: let rec applyPartially f items = | [] -> f | [x] -> f x | head :: tail ->

我有一个我想部分应用于函数的值序列:

let f a b c d e= a+b+c+d+e

let items = [1,2,3,4,5]

let result = applyPartially f items

Assert.Equal(15, result)
我负责applyPartially函数。我尝试过编写如下递归函数:

let rec applyPartially f items =
| [] -> f
| [x] -> f x
| head :: tail -> applyPartially (f head) tail
我遇到的问题是,f类型在我的迭代'a->'b->'c->'d->'e的开始,对于每个循环,它应该消耗一个订单

'a->'b->'c->'d->'e 
'b->'c->'d->'e 
'c->'d->'e 
'd->'e
这意味着我能想到的较低的接口是'd->'e。我如何隐藏函数的复杂性,以便在递归函数中只显示'd->'e?

F#type系统没有一种很好的方法可以按照您建议的方式使用普通函数-要做到这一点,您需要确保列表的长度与函数的参数数量匹配,这在普通列表和函数中是不可能的

然而,您可以使用一个有区别的联合来很好地模拟这一点。您可以定义已完成或需要一个以上输入的分部函数:

type PartialFunction<'T, 'R> = 
  | Completed of 'R
  | NeedsMore of ('T -> PartialFunction<'T, 'R>)
现在,您可以通过解构参数列表并将它们逐个应用于分部函数,来实现
applypartily
,直到得到结果:

let f = 
  NeedsMore(fun a -> NeedsMore(fun b ->
    NeedsMore(fun c -> NeedsMore(fun d ->
      NeedsMore(fun e -> Completed(a+b+c+d+e))))))
let rec applyPartially f items =
  match f, items with
  | Completed r, _ -> r
  | NeedsMore f, head::tail -> applyPartially (f head) tail
  | NeedsMore _, _ -> failwith "Insufficient number of arguments"
以下内容现在返回15个预期值:

applyPartially f [1;2;3;4;5]

免责声明:请不要使用这个。这很简单

正如你所期待的:

let f a b c d e= a+b+c+d+e
apply f [1; 2; 3; 4; 5] //15

非常感谢,我明天会读到这篇文章,我的大脑现在很痛!:)我不是专家,但可以让f=NeedsMore(乐趣a->NeedsMore(乐趣b->NeedsMore(乐趣c->NeedsMore)(乐趣d->NeedsMore(乐趣e->已完成的(a+b+c+d+e‘‘‘‘‘‘)’)封装在计算表达式中吗?@Watson好主意,是的,我想可以!虽然我想它不会使代码比显式版本更好。。。
let f a b c d e= a+b+c+d+e
apply f [1; 2; 3; 4; 5] //15