3

我試圖在F#中編寫一個解釋器。我想檢查表達式的類型。在F#中使用不同的返回類型進行歧視的聯合類型檢查

這裏是我的表達

type Expr = 
| Integer of int 
| String of string 
| Boolean of bool 

這是我使用與

let checkType (e:Expr) = 
match e with 
| String s -> s 
| Integer i -> i 
| Boolean b -> b 

我想要的方法來確定閹一個表達式來檢查類型的方法識別聯合是一個字符串,整數或布爾值。

然而,視覺工作室給我的checkType方法的4線以下錯誤:

This expression was expected to have type string but here has type int 

我這麼想嗎?

+6

當前的錯誤是由於一個事實,即函數只能返回一個類型的表達式 –

回答

6

要擴大約翰·帕爾默的評論:

F#希望每個函數有一個返回類型。例如,您可以編寫一個函數,該函數接受一個int並返回一個int,該函數將是int -> int類型的函數。將字符串解析爲int的函數的類型爲string -> int。等等。

現在,你寫的checkType函數的返回類型是什麼?由於您沒有指定返回類型,因此編譯器會查看可以從函數返回的值的類型 - 每個可能的代碼分支都必須返回一個值,並且它們都必須是相同的類型。所以它看着你的match聲明,看到它的第一個分支返回一個string,並且說:「啊哈!我已經計算出此函數的返回類型;這是一個函數,它需要一個Expr並返回一個字符串。函數的類型是Expr -> string。「

然後看你match語句的第二個分支,並說,「等一下這是返回一個string的功能,但在這個代碼分支它返回一個int這不是有效的:。該代碼調用這個函數需要知道什麼類型期望它返回。「所以你會得到錯誤。現在

,如果你換你的match陳述案件的順序,檢查Integer i第一,那麼編譯器將評估你的函數具有類型Expr -> int(服用Expr輸入並返回int輸出),並拋出一個錯誤在| String s -> s行。這一次,錯誤將是「等一下,這是一個返回int的函數,所以表達式s應該是int類型,但是它的類型是string,這是無效的。」

或刪除| String s -> s行,您將看到一個錯誤「此表達式預計有int類型,但此處有類型bool。」同樣的事情:每個函數只能有一個返回類型。如果你想從一個函數返回多種不同的可能類型,那就是歧視聯盟的用途。請參閱http://fsharpforfunandprofit.com/series/understanding-fsharp-types.html

+0

非常明確的解釋,謝謝。 – k1u

-1

你可以用所有的表達式爲選項類型像一些或字符串:

let checkType (e:Expr) = 
    match e with 
    | String e -> "we are string: " + string e 
    | Integer e-> "we are integer: " + string e 
    | Boolean e -> "we are boolean: " + string e 
相關問題