3

是否可以“扩展” F# 编译器以进行自定义编译时字符串检查?我正在考虑类似于StringFormat使用sprintf等时对字符串的检查。当我说“扩展”时,我并不是说构建编译器的自定义版本,我的意思是使用现有的支持技术。

在我的脑海中,你可能有一种RegexFormat类型。您提供正则表达式,编译器将使用正则表达式进行静态分析。例如

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

如果不是,也许这对我来说是一个类型提供者:) - 如果整个事情是一个糟糕的主意,请告诉我!

4

3 回答 3

7

我们在 Fsharpx 中有一个 Regex 类型的提供程序。

以下是一些示例

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"

这并不完全是您要寻找的东西,但我想您可以轻松地采用此类型提供程序并使用您的静态文字规则对其进行自定义。

于 2012-11-30T10:53:35.090 回答
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()
于 2012-11-30T11:16:49.387 回答
0

Uri最简单的解决方案是执行 BCL 对,等所做的操作,Guid并创建一个解析字符串输入的类型。

我认为修改编译器虽然很有趣,但却是矫枉过正(如您所说,这是一个“可怕的想法”)。

以前也有人问过类似的问题。

于 2012-11-30T15:23:42.187 回答