我可以将类型作为参数传递给此函数吗?
Can I pass a type as a parameter to this function?
以下代码,大部分复制自
工作正常。
module SVMModule
open Accord.MachineLearning
open Accord.MachineLearning.VectorMachines
open Accord.MachineLearning.VectorMachines.Learning
open Accord.Statistics.Kernels
open Accord.Math.Optimization.Losses
// open MathNet.Numerics.LinearAlgebra.Matrix
let inputs = [| [| 0.; 0. |]; [| 0.; 1. |]; [| 1.; 0. |]; [| 1.; 1. |] |]
let xor = [| 0; 1; 1; 0 |]
/// Creates and trains a Support Vector Machine given inputs and outputs.
/// The kernel can be Linear, Gaussian, or Polynomial.
/// The default tolerance is 1e-2.
let train (C: float) (tol: float) (inputs: float [] []) =
let learn = SequentialMinimalOptimization<Gaussian>()
learn.UseComplexityHeuristic <- true
learn.UseKernelEstimation <- true
if C >= 0. then learn.Complexity <- C
if tol > 0. then learn.Tolerance <- tol
let svm = learn.Learn(inputs, xor)
svm
let svm = train 0.5 1e-2 inputs
let prediction = svm.Decide inputs
printfn "SVM_0 Prediction: %A" prediction
我想实现 train
的多态版本,比如
let train (kernel: string) (C: float) (tol: float) (inputs: float [] []) =
let learn =
if kernel = "Gaussian" then
SequentialMinimalOptimization<Gaussian>()
else
SequentialMinimalOptimization<Linear>()
// More code
这不起作用,因为 if
表达式必须 return 在其所有分支中具有相同类型的对象。
我想知道是否有一种方法可以将 Linear
或 Gaussian
作为类型传递给 train
(这些确实是类型),这样我就不必编写一个火车每种类型的功能(trainGaussian
和 trainLinear
)。 Akso,即使我不厌其烦地编写了这些单独的函数,我想也很难根据用户的选择在运行时调用它们,因为 if
语句的相同问题会让人头疼。
我已经使用接口在 F#
中实现了多态性,但使用 classes 是我自己构建的。这些 classes 在 Accord.NET
中,即使它们继承自基础 class,我也无法处理类型问题并实现多态性。
感谢您的任何建议。
简单地将具体类型 Gaussian
替换为 't
之类的类型参数应该很简单(并且可以选择将其作为显式类型参数添加到 train
)。这样做时,我稍微清理了您现有的代码:
let train<'t> (C: float) (tol: float) (inputs: float [] []) =
let learn = SequentialMinimalOptimization<'t>(UseComplexityHeuristic = true, UseKernelEstimation = true)
if C >= 0. then learn.Complexity <- C
if tol > 0. then learn.Tolerance <- tol
learn.Learn(inputs, xor)
然后在调用点,编译器需要通过某种方式知道要使用什么类型,或者通过显式传递它:
let svm = train<Gaussian> 0.5 1e-2 inputs
或依靠类型推断从程序的另一部分流出类型:
let svm:Gaussian = train 0.5 1e-2 inputs
以下代码,大部分复制自
工作正常。
module SVMModule
open Accord.MachineLearning
open Accord.MachineLearning.VectorMachines
open Accord.MachineLearning.VectorMachines.Learning
open Accord.Statistics.Kernels
open Accord.Math.Optimization.Losses
// open MathNet.Numerics.LinearAlgebra.Matrix
let inputs = [| [| 0.; 0. |]; [| 0.; 1. |]; [| 1.; 0. |]; [| 1.; 1. |] |]
let xor = [| 0; 1; 1; 0 |]
/// Creates and trains a Support Vector Machine given inputs and outputs.
/// The kernel can be Linear, Gaussian, or Polynomial.
/// The default tolerance is 1e-2.
let train (C: float) (tol: float) (inputs: float [] []) =
let learn = SequentialMinimalOptimization<Gaussian>()
learn.UseComplexityHeuristic <- true
learn.UseKernelEstimation <- true
if C >= 0. then learn.Complexity <- C
if tol > 0. then learn.Tolerance <- tol
let svm = learn.Learn(inputs, xor)
svm
let svm = train 0.5 1e-2 inputs
let prediction = svm.Decide inputs
printfn "SVM_0 Prediction: %A" prediction
我想实现 train
的多态版本,比如
let train (kernel: string) (C: float) (tol: float) (inputs: float [] []) =
let learn =
if kernel = "Gaussian" then
SequentialMinimalOptimization<Gaussian>()
else
SequentialMinimalOptimization<Linear>()
// More code
这不起作用,因为 if
表达式必须 return 在其所有分支中具有相同类型的对象。
我想知道是否有一种方法可以将 Linear
或 Gaussian
作为类型传递给 train
(这些确实是类型),这样我就不必编写一个火车每种类型的功能(trainGaussian
和 trainLinear
)。 Akso,即使我不厌其烦地编写了这些单独的函数,我想也很难根据用户的选择在运行时调用它们,因为 if
语句的相同问题会让人头疼。
我已经使用接口在 F#
中实现了多态性,但使用 classes 是我自己构建的。这些 classes 在 Accord.NET
中,即使它们继承自基础 class,我也无法处理类型问题并实现多态性。
感谢您的任何建议。
简单地将具体类型 Gaussian
替换为 't
之类的类型参数应该很简单(并且可以选择将其作为显式类型参数添加到 train
)。这样做时,我稍微清理了您现有的代码:
let train<'t> (C: float) (tol: float) (inputs: float [] []) =
let learn = SequentialMinimalOptimization<'t>(UseComplexityHeuristic = true, UseKernelEstimation = true)
if C >= 0. then learn.Complexity <- C
if tol > 0. then learn.Tolerance <- tol
learn.Learn(inputs, xor)
然后在调用点,编译器需要通过某种方式知道要使用什么类型,或者通过显式传递它:
let svm = train<Gaussian> 0.5 1e-2 inputs
或依靠类型推断从程序的另一部分流出类型:
let svm:Gaussian = train 0.5 1e-2 inputs