2016-03-30 55 views
0

我想要一個函數返回一種或另一種類型。有沒有什麼辦法在F#中編寫這個而不是創建一個新的歧視聯合類型並將該歧視聯盟從函數中返回?F#:從一個函數返回不同類型的值

下面是一個簡單的例子,就不會編譯:

type Json = JNumber of float 
      | JString of string 
      | JArray of seq<Json> 
      | JObject of Map<string, Json> 
      | JBool of bool 
      | JNull 

let parseJson(jason:Json) = match jason with 
          |JNumber num -> num 
          |JString str -> str 
          |JArray arr -> arr |> Seq.map (fun e -> parseJson e) 
          |JObject obj -> obj |> Seq.map (fun (k,v) -> (k, parseJson v)) |> Map.ofArray 
          |JBool boo -> boo 
          |JNull  -> None 

基本上我希望能夠把一個JSON對象到F#的數據結構。 (對於一些背景,我正在編寫一個玩具json解析器,它可以在單獨的步驟中轉換文本 - > Json對象 - > F#數據結構)

+3

這已經被問了一大堆的時候,這是不是真的有可能。簡單的原因是,假設你使用'let x = parseJson'什麼是'x'類型 - 如果x + 1行被編譯?等 –

+0

@JohnPalmer是不是這是一個類型提供者是什麼?我的意見是,這個問題是不正確的,但答案是創建一個「類型提供者」...對於gnicholas:https://msdn.microsoft.com/en-us/library/hh361034.aspx或檢查出這一點: http://fsharp.github.io/FSharp.Data/library/JsonProvider.html以及https://github.com/fsharp/FSharp.Data/tree/master/src/Json的源代碼 –

+0

@HelgeReneUrholm請注意,類型提供者實際返回的是一個複雜的類型。它實際上需要一個模板文件,以便它可以在編譯時生成類型。如果您在運行時使用新文件,則它需要與模板 –

回答

1

這不是一個好主意,在你的情況下,你幾乎想要返回一個聯合點。想想如何使用這樣的功能,你不能模式匹配。

對於像這樣的函數來說,你可以使用box來鑄造每一個obj對象的值,但是每次你需要使用parseJson函數時,你都會陷入鑄造的狀態它會工作,但它不會很好。

我說的是這樣的: https://stackoverflow.com/a/2994300/1485641

+1

這就是我想的。但值得一問。謝謝! – gnicholas