Sco*_*rod 0 f# functional-programming
签名末尾的冒号后跟一个类型是否具有不同的含义,具体取决于它是否附加到函数而不是方法?
这与我过去发布的问题有关.但是,这个问题是基于一种方法的背景.
例如,执行以下功能:
type StateResponse<'state, 'event> = ('state * 'event) -> 'state
// Account * Event -> Account
let update1 : StateResponse<Account,Event> = function
| account , LoggedIn credentials -> account
| account , Deposited balance -> { account with Balance=account.Balance + balance }
| account , Withdrew balance -> { account with Balance=account.Balance - balance }
// Account ** Doesn't compile**
let update2 : Account = function
| account , LoggedIn credentials -> account
| account , Deposited balance -> { account with Balance=account.Balance + balance }
| account , Withdrew balance -> { account with Balance=account.Balance - balance }
// Account * Event -> Account
let update3 = function
| account , LoggedIn credentials -> account
| account , Deposited balance -> { account with Balance=account.Balance + balance }
| account , Withdrew balance -> { account with Balance=account.Balance - balance }
// state:Account * event:Event -> Account
let update4 (state , event) =
match state , event with
| account , LoggedIn credentials -> account
| account , Deposited balance -> { account with Balance=account.Balance + balance }
| account , Withdrew balance -> { account with Balance=account.Balance - balance }
// state:StateResponse<Account,Event> * event:Event -> StateResponse<Account,Event> ** Doesn't compile**
let update5 (state , event) : StateResponse<Account,Event> =
match state , event with
| account , LoggedIn credentials -> account
| account , Deposited balance -> { account with Balance=account.Balance + balance }
| account , Withdrew balance -> { account with Balance=account.Balance - balance }
Run Code Online (Sandbox Code Playgroud)
函数上下文 - 表示函数的别名?
我假定当一个冒号后面是函数类型被附加到函数名称的末尾,则该函数名成为别名到功能类型的结肠后到来.这与用于为函数或元组元素的参数提供别名的约定相同.
注意:
我假设在函数签名的冒号(即update2)之后不能附加不反映函数的类型.
我也有理由相信函数签名别名的函数名称不能在冒号之前声明显式参数(即update5).
方法上下文 - 表示返回类型?
我假设当一个冒号后跟一个类型被附加到方法名后跟参数的末尾时,那么末尾附加的那个类型可以是一个任意类型(无论它是否是一个函数签名).如果应用,这与功能上下文相反.
我的假设是否准确?
附录:
namespace Domain
module EventSourcing =
type StateResponse<'state, 'event> = ('state * 'event) -> 'state
module Account =
open EventSourcing
type AccountId = AccountId of string
type FirstName = FirstName of string
type LastName = LastName of string
type Credentials = { UserId:string; Password:string }
type Account = {
AccountId: AccountId
FirstName: FirstName
LastName: LastName
Balance: decimal }
and Event =
| LoggedIn of Credentials
| Deposited of balance: decimal
| Withdrew of balance: decimal
(*Functions*)
let getAccount credentials = {
AccountId= AccountId "myAccountId"
FirstName= FirstName "Scott"
LastName= LastName "Nimrod"
Balance= 20000m }
let update1 : StateResponse<Account,Event> = function
| account , LoggedIn credentials -> account
| account , Deposited balance -> { account with Balance=account.Balance + balance }
| account , Withdrew balance -> { account with Balance=account.Balance - balance }
let update2 : Account = function
| account , LoggedIn credentials -> account
| account , Deposited balance -> { account with Balance=account.Balance + balance }
| account , Withdrew balance -> { account with Balance=account.Balance - balance }
let update3 = function
| account , LoggedIn credentials -> account
| account , Deposited balance -> { account with Balance=account.Balance + balance }
| account , Withdrew balance -> { account with Balance=account.Balance - balance }
let update4 (state , event) =
match state , event with
| account , LoggedIn credentials -> account
| account , Deposited balance -> { account with Balance=account.Balance + balance }
| account , Withdrew balance -> { account with Balance=account.Balance - balance }
let update5 (state , event) : StateResponse<Account,Event> =
match state , event with
| account , LoggedIn credentials -> account
| account , Deposited balance -> { account with Balance=account.Balance + balance }
| account , Withdrew balance -> { account with Balance=account.Balance - balance }
Run Code Online (Sandbox Code Playgroud)
冒号表示剩下的类型.所以,当你写let x : T = ...
,你说的类型x
是T
.这里T
应该匹配之后的任何类型=
.因此,如果这是一个函数,T
应该是兼容的函数类型,如果它是其他东西,T
应该是其他东西.
例如let x : int = 42
,因为没有类型而没有类型,所以let x : int -> int = function y -> y+1
有效let x : int -> int = 42
或let x : int = function y -> y+1
不有效.42
int -> int
function y -> y+1
int
现在当你使用快捷语法来定义函数时let f (x: ParameterType) : T
,那么最后一个冒号的左边是什么f(x : ParameterType)
,而不是f
.所以你现在要说的是什么类型f(x)
(换句话说是什么类型的返回类型f
),而不是类型f
是什么.而且这种类型应该与之后的类型相匹配=
.
PS:两者let f = function x -> ...
(或者就此而言let f = fun x -> ...
)并且let f x = ...
完全等效并定义函数.方法是使用member
关键字定义的,似乎与您的问题无关.