在与Idris打交道后,我已经成为使用明确类型的巨大粉丝,通过更频繁地在我的函数中明确写入类型并使用类型别名来加强我的F#程序的声明性自我文档。为什么F#有两种类型的显式类型声明?
定义我的功能与显式类型让我(重新)发现F#实际上有两种功能显式类型的样式。有使用:
的标准let函数样式,并且有使用->
的lambda函数。
例如
// explicitly typed function using the classical let ':' style
let OK1 (content : string) (context : Context) : Async<Context option> =
{ context with Response = { Content = content; StatusCode = 200 } }
|> Some
|> async.Return
// explicitly typed function using the '->' style
let OK2 : string -> Context -> Async<Context option> = fun content context ->
{ context with Response = { Content = content; StatusCode = 200 } }
|> Some
|> async.Return
有关->
风格的好处是,我可以定义类型别名,如
// type alias defining a webpart
type WebPart = Context -> Async<Context option>
// using the type alias in the declaration of an explicitly typed function
let OK2 : string -> WebPart = fun content context ->
{ context with Response = { Content = content; StatusCode = 200 } }
|> Some
|> async.Return
我不认为这是可能的声明和使用相同的使用:
样式输入别名...?
我很疑惑,为什么F#有两种风格的函数声明显式类型。它是否有某种.Net限制?还是它有一些特殊用途? 为什么不直接用->
而不是:
定义所有显式类型?
我同意上述案例。虽然这个例子似乎与显式类型无关。我最感兴趣的是为什么显式类型定义在lambda风格和'普通'风格之间不同。在'正常'风格下,你似乎放弃了在显式类型声明中使用类型别名的能力,比如'type WebPart = Context - > Async'。 –
Michelrandahl
比较http://stackoverflow.com/questions/39394254/value-restriction-the-type-bar-has-been-inferred-to-have-generic-type。有鉴于此,“两种选择完全相同”的说法可能不成立。不知道,但。 – BitTickler
是的,这个概念确实适用于这种情况。 'foo'是一个常规函数,它的定义相当于'let foo a b = ...',但'bar'是不同的。 –