2012-11-30 40 views
3

是否有可能「擴展」F#編譯器以執行自定義編譯時字符串檢查?當我使用sprintf等時,我正在考慮類似StringFormat字符串的檢查。當我說「擴展」時,我並不意味着構建定製版本的編譯器,我的意思是使用現有的支持技術。自定義F#編譯器字符串檢查

關閉我的頭頂,你可能有一個RegexFormat類型。您提供了正則表達式,編譯器將使用正則表達式進行靜態分析。例如。

//Setup RegexFormat with IP address regex and type abbreviation IpRegexFormat? 
//Compile error. ipAddress expects IpRegexFormat! 
let ip = ipAddress "192.168.banana.1" 

如果沒有,也許這對我來說是一個:)類型提供商 - 如果整個事情是一個可怕的想法,讓我知道!

+0

是的,這是可能的。不,不要這樣做。試着看看類型提供者是否爲你做。 –

+0

很想聽到更多@RamonSnir。如何和爲什麼不! – bentayloruk

+0

幾年前,我已經對F#做了幾處修改。雖然這很有趣,結果是更好的F# - 它需要時間,Visual Studio不支持它,而類型提供者可以完成大部分工作(免責聲明:我不喜歡類型提供者,沒有使用他們在幾周內)。 –

回答

7

我們在Fsharpx有一個Regex類型的提供者。

這裏有一些samples

type PhoneRegex = Regex< @"(?<AreaCode>^\d{3})-(?<PhoneNumber>\d{3}-\d{4}$)"> 

[<Test>] 
let ``Can call typed IsMatch function``() =  
    PhoneRegex.IsMatch "425-123-2345" 
    |> should equal true 

[<Test>] 
let ``Can call typed CompleteMatch function``() =  
    PhoneRegex().Match("425-123-2345").CompleteMatch.Value 
    |> should equal "425-123-2345" 

[<Test>] 
let ``Can return AreaCode in simple phone number``() = 
    PhoneRegex().Match("425-123-2345").AreaCode.Value 
    |> should equal "425" 

[<Test>] 
let ``Can return PhoneNumber property in simple phone number``() = 
    PhoneRegex().Match("425-123-2345").PhoneNumber.Value 
    |> should equal "123-2345" 

這不是你在尋找什麼,但我想你可以輕鬆拍攝這種類型的提供商,並與你的靜態文本的規則定製。

+2

哦,是的!我忘記了我們已經有了FSharpx中的所有類型提供者:)我可以這樣。唯一的問題是我想用fs腳本中使用的工具發佈它。任何想法在這種情況下類型提供者安全模型會做什麼? – bentayloruk

+0

我不確定。你必須嘗試。在MonoDevelop,Visual Studio或FSI中可能會有所不同。 – forki23

1

我認爲這裏的真正的答案是使用DU -

type ip = 
|IP of byte * byte * byte * byte 
member x.ToString() = 
    match x with 
    |IP(a,b,c,d) -> sprintf "%i.%i.%i.%i" 

然後編譯的時候檢查只是

let actualip = IP(1uy,1uy,1uy,1uy).ToString() 
+1

爆炸,IP是一個壞榜樣。 DU會爲IP工作,但不會像「字符串必須是電子郵件地址」。我對更通用的解決方案感興趣(或者爲什麼更通用的解決方案會很糟糕:)。 – bentayloruk

+0

@bentayloruk - 你可以爲電子郵件地址定義一個類似的DU--但是對於更普遍/更聰明的東西,你可能需要一個類型提供者 - 特別是如果你想編譯時檢查 –

+0

是的,這是編譯時檢查我後。我想要sprintf體驗所有的字符串! :) 感謝您的輸入。 – bentayloruk

0

最簡單的方法是做什麼的BCL有Uri做,Guid等,並創建一個解析字符串輸入的類型。

我想修改編譯器,而有趣的是大材小用(一個「可怕的想法,」像你說的)。

一個similar question已經問。