【问题标题】:How to pass same parameters to multiple functions?如何将相同的参数传递给多个函数?
【发布时间】:2016-04-26 23:42:38
【问题描述】:

我有一堆函数,我想用相同的输入来计算。有没有比我在下面选择的方式更好的方式来查看输出?

open MathNet.Numerics.Distributions

// The functions
let EuVanillaPut S0 K T r sigma = 
    let d1 = (log(S0/K) + (r + sigma ** 2.0 / 2.0) * T)/(sqrt(T)*sigma)
    let d2 = d1 - sqrt(T)*sigma
    K*exp(-r*T)*Normal.CDF(0.0,1.0,-d2) - S0*Normal.CDF(0.0,1.0,-d1)

let BSMdelta S0 K T r sigma = 
    let d1 = (log(S0/K) + (r + sigma ** 2.0 / 2.0) * T)/(sqrt(T)*sigma)
    Normal.CDF(0.0,1.0,d1)

let BSMgamma S0 K T r sigma = 
    let d1 = (log(S0/K) + (r + sigma ** 2.0 / 2.0) * T)/(sqrt(T)*sigma)
    Normal.PDF(0.0,1.0,d1) / (S0 * sigma * sqrt(T))

let BSMvega S0 K T r sigma = 
    let d1 = (log(S0/K) + (r + sigma ** 2.0 / 2.0) * T)/(sqrt(T)*sigma)
    Normal.PDF(0.0,1.0,d1) * S0 * sqrt(T)

let BSMthetacall S0 K T r sigma = 
    let d1 = (log(S0/K) + (r + sigma ** 2.0 / 2.0) * T)/(sqrt(T)*sigma)
    let d2 = d1 - sqrt(T)*sigma
    -S0 * Normal.PDF(0.0,1.0,d1) * sigma / (2.0*sqrt(T)) - r*K*exp(-r*T)*Normal.CDF(0.0,1.0,d2)

let BSMthetaput S0 K T r sigma = 
    let d1 = (log(S0/K) + (r + sigma ** 2.0 / 2.0) * T)/(sqrt(T)*sigma)
    let d2 = d1 - sqrt(T)*sigma
    -S0 * Normal.PDF(0.0,1.0,d1) * sigma / (2.0*sqrt(T)) + r*K*exp(-r*T)*Normal.CDF(0.0,1.0,-d2)

// Calling them all at once on the same inputs
// So ugly! Is there a better way?
(30.0, 25.0, 5.0, 0.02, 0.05)
|> fun (S0, K, T, r, sigma) -> [EuVanillaPut S0 K T r sigma; 
                                BSMdelta S0 K T r sigma; 
                                BSMgamma S0 K T r sigma;
                                BSMvega S0 K T r sigma;
                                BSMthetacall S0 K T r sigma;
                                BSMthetaput S0 K T r sigma]

我对 F# 很陌生,我应该为此创建一个类型吗?我应该使用不同的数据结构作为函数的输入吗?非常感谢任何和所有指针。

【问题讨论】:

  • 可能这更适合 codereview.se,但您始终可以列出函数并使用 List.map
  • 另外,如果您正在处理具有五个元素的元组,则记录类型可能更易于阅读和处理。
  • +1 用于记录。它使以后的重构更容易(例如,添加一个参数)。你也减少了混淆你的论点的机会——它们现在都是浮动的。

标签: f#


【解决方案1】:

按照 cmets 的建议,一种选择是创建一个函数列表,然后使用 List.map 遍历所有函数并调用它们:

let results = 
  [ EuVanillaPut; BSMdelta; BSMgamma ] 
  |> List.map (fun f -> f 30.0 25.0 5.0 0.02 0.05)

我想您还想提取单个结果 - 为此,您可以使用模式匹配(但您会收到警告,因为编译器无法知道列表中的元素数量是否正确) :

let [euVanillaPut; bsmdelta; bsmgamma] = results

为了避免警告,你必须写:

match results with
| [euVanillaPut; bsmdelta; bsmgamma] -> // all good
| _ -> failwith "This should not happen..."

或者,您可以更改函数定义以使用元组(或记录):

let EuVanillaPut (S0, K, T, r, sigma) = 
    let d1 = (log(S0/K) + (r + sigma ** 2.0 / 2.0) * T)/(sqrt(T)*sigma)
    let d2 = d1 - sqrt(T)*sigma
    K*exp(-r*T)*Normal.CDF(0.0,1.0,-d2) - S0*Normal.CDF(0.0,1.0,-d1)

然后您可以定义一个元组来保存参数并将其用作多个函数的参数:

let ps = (30.0, 25.0, 5.0, 0.02, 0.05)

let euVanillaPut = EuVanillaPut ps
let bsmdelta = BSMdelta ps
let bsmgamma = BSMgamma ps 

第一种方法是一个巧妙的技巧,但如果您经常这样做,那么从列表中提取单个结果会有点难看。如果您有许多具有相同参数组的函数,则第二种方法更简单且更有意义。

【讨论】:

    猜你喜欢
    • 2013-06-28
    • 1970-01-01
    • 2020-11-08
    • 2023-04-04
    • 1970-01-01
    • 2016-04-02
    • 1970-01-01
    • 2018-03-26
    • 2016-01-17
    相关资源
    最近更新 更多