F#中字符串的编译时约束,类似于度量单位-可能吗? [英] Compile-time constraints for strings in F#, similar to Units of Measure - is it possible?

查看:54
本文介绍了F#中字符串的编译时约束,类似于度量单位-可能吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用F#开发Web应用程序.考虑保护用户输入字符串免受SQL,XSS和其他漏洞的侵害.

I'm developing a Web application using F#. Thinking of protecting user input strings from SQL, XSS, and other vulnerabilities.

用两个词,我需要一些编译时约束,使我能够将普通字符串与表示SQL,URL,XSS,XHTML等的字符串区别开来.

In two words, I need some compile-time constraints that would allow me discriminate plain strings from those representing SQL, URL, XSS, XHTML, etc.

许多语言都有它,例如Ruby的本机字符串内插功能#{...}.
对于F#,似乎度量单位效果很好,但是它们仅适用于数字类型.
有几种采用运行时 UoM的解决方案(链接),但是我认为这是我实现目标的开销.

Many languages have it, e.g. Ruby’s native string-interpolation feature #{...}.
With F#, it seems that Units of Measure do very well, but they are only available for numeric types.
There are several solutions employing runtime UoM (link), however I think it's an overhead for my goal.

我研究了FSharpPowerPack,似乎很可能为字符串提出类似的东西:

I've looked into FSharpPowerPack, and it seems quite possible to come up with something similar for strings:

[<MeasureAnnotatedAbbreviation>] type string<[<Measure>] 'u> = string
// Similarly to Core.LanguagePrimitives.IntrinsicFunctions.retype
[<NoDynamicInvocation>]
let inline retype (x:'T) : 'U = (# "" x : 'U #)
let StringWithMeasure (s: string) : string<'u> = retype s

[<Measure>] type plain
let fromPlain (s: string<plain>) : string =
    // of course, this one should be implemented properly
    // by invalidating special characters and then assigning a proper UoM
    retype s

// Supposedly populated from user input
let userName:string<plain> = StringWithMeasure "John'); DROP TABLE Users; --"
// the following line does not compile
let sql1 = sprintf "SELECT * FROM Users WHERE name='%s';" userName
// the following line compiles fine
let sql2 = sprintf "SELECT * FROM Users WHERE name='%s';" (fromPlain userName)

注意:这只是一个示例;不建议使用SqlParameter. :-)

Note: It's just a sample; don't suggest using SqlParameter. :-)

我的问题是:是否有一个像样的图书馆?有可能添加语法糖吗?
谢谢.

My questions are: Is there a decent library that does it? Is there any possibility to add syntax sugar?
Thanks.

更新1 :感谢Daniel,我需要编译时约束.

Update 1: I need compile-time constraints, thanks Daniel.

更新2 :我正在尝试避免任何运行时开销(元组,结构,有区别的联合等).

Update 2: I'm trying to avoid any runtime overhead (tuples, structures, discriminated unions, etc).

推荐答案

有点晚了(我确定有一种时间格式,在2月23日至11月30日之间只有一点不同),我相信这些单线与您的目标兼容:

A bit late (I'm sure there's a time format where there is only one bit different between February 23rd and November 30th), I believe these one-liners are compatible for your goal:

type string<[<Measure>] 'm> = string * int<'m>

type string<[<Measure>] 'm> = { Value : string }

type string<[<Measure>] 'm>(Value : string) = struct end

这篇关于F#中字符串的编译时约束,类似于度量单位-可能吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆