2017-02-11 8 views
0

シグネチャの最後にタイプが続くコロンは、関数にメソッドを追加するかどうかによって異なる意味を持ちますか?シグネチャの最後にコロンが続くタイプは、コンテキストに基づいて異なる意味を持ちますか?

これは過去に投稿したquestionに関連しています。しかし、その質問はの方法の文脈に基づいていました。例えば

、以下の機能を取る:

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 } 

関数コンテキストを - 関数に別名を表しますか?

は、私が想定している関数型コロンが関数名はコロンの後に来る関数型へのエイリアスなると、その後、関数名の最後に追加されたとき。これは、関数またはタプル要素のパラメータのエイリアスを提供するために使用されるのと同じ規則です。

注:

I機能を反映していないタイプの関数署名(アップデート2すなわち)のコロンの後に追加されないことができないと仮定する。

また、関数シグネチャのエイリアスには、コロンの前に明示的に宣言されたパラメータ(つまり、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 } 

答えて

6

コロンはそれで残っているものの種類を表します。したがって、let x : T = ...と書くと、xのタイプがTであると言われます。ここでTは、=の後に来るものと一致するはずです。したがって、それが関数なら、Tは互換性のある関数型でなければなりません。何か他のものなら、Tはそれ以外のものでなければなりません。 42はタイプintを持っていないタイプint -> intfunction y -> y+1を持っていないためlet x : int -> int = 42またはlet x : int = function y -> y+1はないだろうしながら、たとえばlet x : int = 42については

let x : int -> int = function y -> y+1は両方とも有効です。

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キーワードを使用して定義されており、あなたの質問に関連していないようです。

関連する問題