Explicit type parameters in let bindings in classes

我只是一个虾纸丫 提交于 2021-02-08 13:14:10

问题


When I try to create some class like

type MyType () =
    let func<'T> () = ()

The compiler says that there's an error:

Explicit type parameters may only be used on module or member bindings

But the MSDN says:

A let binding at the module level, in a type, or in a computation expression can have explicit type parameters. A let binding in an expression, such as within a function definition, cannot have type parameters.

Why documentation and compiler say different things?


回答1:


This appears to be a syntactic restriction on let bindings inside a class. However, you can still define a generic local function, you just have to specify the type parameters in type annotations:

type MyType () =
   let func (x : 'T) : 'T = x

I do not think this is explicitly syntactically forbidden by the specification, because the specification says that a class definition has the following structure:

type type-name patopt as-defnopt =
      class-inherits-declopt
      class-function-or-value-defnsopt
      type-defn-elements

and class-or-value-defn is defined as:

class-function-or-value-defn := attributesoptstaticoptlet recopt function-or-value-defns

where function-or-value-defns may be a function definition with explicit type parameters:

function-defn :=
inlineoptaccessopt ident-or-op typar-defnsopt argument-pats return-typeopt = expr




回答2:


To add to Tomas's answer, if you need a type parameter but won't have a value of that type you can use a type with a phantom type parameter. e.g.:

open System

type Foo() =
    member x.PrintType<'T> () = printfn "%s" typeof<'T>.Name

type TypeParameter<'a> = TP

let foo = Foo ()

let callFoo (typeParameter : TypeParameter<'a>) =
    foo.PrintType<'a> ()

callFoo (TP : TypeParameter<string>)
callFoo (TP : TypeParameter<DateTime>)


来源:https://stackoverflow.com/questions/13396234/explicit-type-parameters-in-let-bindings-in-classes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!