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