2017-01-16 72 views
1

通用TryValue类型的语法是什么,它可以返回值'a或错误'b?f#歧义联合通用

type TryValue = 
    | Value of 'a 
    | Error of 'b 

如果错误是一个字符串,那么它的罚款:

type 'a TryValue = 
    | Value of 'a 
    | Error of string 

我想定义一个tryRun函数,它接受一个错误的创造者,一个功能和参数,将尝试运行的功能用参数和在任何错误使用错误创建者函数创建了一个错误:

let tryRun createErrorFn param fn = 
    try 
     Value (fn param) 
    with 
     | ex -> Error (createErrorFn ex.Message param) 

而对于任何功能的包装,以由tryRun包裹:

let wrapTryRun createErrorFn fn param = 
    match param with 
    | Value a -> tryRun createErrorFn a fn 
    | Error e -> Error e 

现在我可以运行的功能列表(伪代码,还没有完全制定了这一点):

let createErrorFn errorMessage param = 
    URLProcessignError {url=param.url;errorMessage=errorMessage} 
[fn1;fn2] |> List.fold (fun acc fn -> (wrapTryRun createErrorFn fn acc)) 
+1

看起来像有结果类型在[F#4.1](https://blogs.msdn.microsoft.com/dotnet/2016/07/25/a-peek-into-f-4-1/) – s952163

回答

4

你缺少通用的参数在左侧:

type TryValue<'a,'b> = 
    | Value of 'a 
    | Error of 'b 

当只有一个参数时,您可以像使用字符串一样使用ML样式,但如果您有多个参数,则应使用带有尖括号的.NET符号。

2

其实,老ML风格也可以用多种类型的参数,通过指定一个元组使用:

type ('a, 'b) TryValue = 
    | Value of 'a 
    | Error of 'b 

不过,我相信我读旧的语法已经过时......

+1

我不认为这是真的被弃用,只是不建议你自己的类型。许多人遵循编译器通常的输出语法,对于其他类型的列表和选项以及C#样式等内置类型,使用ML样式;我个人更喜欢在任何地方使用C#风格来保持一致性。 – Tarmil

+0

将ML转换为F#时,ml样式派上用场。如果ML风格贬值,则将ML更难转换为F#。 –