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に正規表現タイプのプロバイダーがあります。

ここにいくつかのサンプルがあります:

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

最も簡単な解決策は、BCL が 、 などで行ったことを行いUriGuid文字列入力を解析する型を作成することです。

コンパイラを変更するのは興味深いことですが、やり過ぎだと思います (あなたが言うように、「ひどい考え」です)。

同様の質問が以前に尋ねられました。

于 2012-11-30T15:23:42.187 に答える