我是F#和函数式编程的新手,需要一些帮助。我来自c#所以我的心态仍然会受到影响。
我需要将一些选项传递给一个函数,并且我使用了一个记录。其中一个选项是延续功能单元 - >选项<' a取代。我无法弄清楚如何定义记录类型。以下是我一直在尝试的例子。
type Func2<'a> = 'a -> 'a option
type ProcessOptions = {
func1: int -> int option
func2: Func2<int> // This works...
//func2: Func2<'a> // ... but this is what I'm trying to achieve - so that I can pass any Func2<'a> using this record.
}
let f1 a =
let r = Some a
printfn "f1: %A" r |> ignore
r
let f2 (a:'a) =
let r = Some a
printfn "f2: %A" r |> ignore
r
let f3 (processOptions:ProcessOptions) =
processOptions.func1(3) |> ignore
processOptions.func2 789 |> ignore
()
let f4 (processOptions:ProcessOptions) =
processOptions.func1(4) |> ignore
//processOptions.func2 "abc" |> ignore // as a result this does not work...
()
[<EntryPoint>]
let main argv =
f1(1) |> ignore
f2 123 |> ignore
f2 "abc" |> ignore
let fo = {
func1 = f1
func2 = f2
}
f3 fo
let fo1 = {
func1 = f1
func2 = f2
}
f4 fo1
0
答案 0 :(得分:1)
在这里你需要使记录具有通用性 - 有点像
type ProcessOptions<'a> = {
func1: int -> int option
func2: Func2<'a> // ... but this is what I'm trying to achieve - so that I can pass any Func2<'a> using this record.
}
答案 1 :(得分:1)
记录中的成员不能是通用函数(可以使用不同类型的参数调用,例如|
或int
)。它总是有一个固定的类型。
您可以使用的技巧是使用通用方法定义一个简单的接口:
string
现在记录中的成员只能是type Func =
abstract Invoke<'a> : 'a -> 'a option
类型(没有泛型类型参数),但Func
内的Invoke
方法将是通用的:
Func
创建type ProcessOptions =
{ func1: Func
func2: Func }
值比编写普通函数要困难一些,但是你可以使用对象表达式:
Func
您现在可以传递let f1 =
{ new Func2 with
member x.Invoke(a) =
let r = Some a
printfn "f1: %A" r |> ignore
r }
并使用不同类型的参数调用ProcessOptions
方法:
Invoke