如何定义类型参数列表?

时间:2016-06-21 14:17:44

标签: generics f#

给出以下类型及其apply

的成员实现
type Result<'TSuccess, 'TError> =
    | Success of 'TSuccess
    | Error of 'TError
    with
    member this.apply (fn:'a) : 'b =
        match (fn, this) with
        | Success(f), Success(x) -> Success(f x)
        | Error(e), Success(_) -> Error(e)
        | Success(_), Error(e) -> Error(e)
        | Error(e1), Error(e2) -> Error(List.concat [e1;e2]);;

我收到此警告(其中包括)

  member this.apply (fn:'a) : 'b =
         -----------^^^^
  /Users/robkuz/stdin(385,12): warning FS0064: This construct causes code to 
  be less generic than indicated by the type annotations. The type variable 
  'TError has been constrained to be type ''a list'.

这个错误

type Result<'TSuccess, 'TError> =
-----------------------^^^^^^^
/Users/robkuz/stdin(381,24): error FS0663: This type parameter has been used 
in a way that constrains it to always be ''a list'

我尝试将其更改为

type Result<'TSuccess, 'TError list> =

type Result<'TSuccess, List<'TError>> =

两者都给我一个语法错误。

我该怎么做才能解决这个问题?

1 个答案:

答案 0 :(得分:4)

正如@ildjarn正确地说,您需要更改Error案例的定义。不过,这会给你关于'b的进一步警告。最好的办法是剥离所有类型的注释,然后让F#完成工作:

    type Result<'TSuccess, 'TError> =
    | Success of 'TSuccess
    | Error of 'TError list
    with
    member this.apply fn =
        match fn, this with
        | Success f, Success x -> Success (f x)
        | Error e, Success _ -> Error e
        | Success _, Error e -> Error e
        | Error e1, Error e2 -> Error (List.append e1 e2)

我认为如果你写了更多关于这种类型的计划会有所帮助 - apply函数的类型为Result<('TSuccess->'a),'TError>->Result<'a,'TError>这是否意味着:在成功的情况下,你会得到一个来自一个来源的函数,来自另一个来源的值,你将一个来源应用于另一个来源吗?