Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
自定义F#编译器字符串检查_F# - Fatal编程技术网

自定义F#编译器字符串检查

自定义F#编译器字符串检查,f#,F#,是否可以“扩展”F#编译器以执行自定义编译时字符串检查?在使用sprintf等时,我正在考虑类似于对StringFormat字符串的检查。当我说“扩展”时,我不是指构建编译器的自定义版本,而是指使用现有支持的技术 在我脑海中,你可能有一个RegexFormat类型。您提供了正则表达式,编译器将使用正则表达式进行静态分析。例如 //Setup RegexFormat with IP address regex and type abbreviation IpRegexFormat? //Compi

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

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

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

如果不是,也许这是我的一个类型提供者:)-如果整个事情是一个糟糕的想法,让我知道

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

以下是一些:

type PhoneRegex=Regex<@“(?^\d{3})-(?\d{3}-\d{4}$)”>
[] 
let``可以调用类型化IsMatch函数``()=
PhoneRegex.IsMatch“425-123-2345”
|>应该等于真的
[] 
让``可以调用类型化的CompleteMatch函数``()=
PhoneRegex().Match(“425-123-2345”).CompleteMatch.Value
|>应等于“425-123-2345”
[] 
让``可以返回简单电话号码中的区号`()=
PhoneRegex().Match(“425-123-2345”).AreaCode.Value
|>应等于“425”
[] 
让``可以在简单电话号码`()中返回PhoneNumber属性=
PhoneRegex().Match(“425-123-2345”).PhoneNumber.Value
|>应等于“123-2345”

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

我认为真正的答案是使用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()

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

我认为修改编译器虽然很有趣,但却太过了(正如你所说的“糟糕的想法”)


A以前有人问过。

是的,有可能。不,不要这样做。试试看类型提供者是否为你做了这件事。希望听到更多@RamonSnir。怎么做,为什么不呢!几年前我对F#做了几次修改。虽然这很有趣,结果是一个更好的F#-这需要时间,Visual Studio不支持它,类型提供程序可以完成大部分工作(免责声明:我不喜欢类型提供程序,已经好几个星期没有使用它们了)。啊,我明白了。你的意思是实际修改编译器。这个问题我问得不够清楚。当我说“扩展”时,我的意思是通过合法的扩展点(即内联类型/属性),而不是自定义构建。可能是重复的哦,是的!我忘了在FSharpx中已经有了所有的类型提供程序:)我可以这样做。唯一的一个问题是,我想在一个从fs脚本使用的工具中发布它。知道类型提供程序安全模型在这种情况下的作用吗?我不确定。你必须试一试。在MonoDevelop、VisualStudio或FSI中可能会有所不同。Blast、IP是一个糟糕的例子。DU将为IP工作,但不是“字符串必须是电子邮件地址”之类的东西。我对一个更通用的解决方案感兴趣(或者为什么一个更通用的解决方案会不好:)@bentayloruk-你可以为电子邮件地址定义一个类似的DU-但是对于更通用/更聪明的东西,你可能需要一个类型提供者-特别是如果你想要编译时检查是的,我要的是编译时检查。我想要所有字符串的sprintf体验!:)谢谢您的输入。@JohnPalmer您如何定义电子邮件地址的类型?我的意思是一个真正的类型安全版本。你可以做很多运行时检查电子邮件地址,这是真的。但是类型提供程序可以尝试向给定地址发送电子邮件,如果服务器出现故障,则会引发编译错误;-)可能有点慢,但这是一个完整的新世界。
let actualip = IP(1uy,1uy,1uy,1uy).ToString()