变异状态是构建器模式的中心.有没有一种惯用的方法来实现F#中这样一个类的内部,它将减少/消除可变状态,同时保留通常的接口(这个类主要用于其他.NET语言)?
这是一个天真的实现:
type QueryBuilder<'T>() = //'
let where = ref None
let orderBy = ref None
let groupBy = ref None
member x.Where(cond) =
match !where with
| None -> where := Some(cond)
| _ -> invalidOp "Multiple WHERE clauses are not permitted"
// members OrderBy and GroupBy implemented similarly
Run Code Online (Sandbox Code Playgroud)
一种想法是创建一个记录类型来存储内部,并使用复制和更新表达式.
type private QueryBuilderSpec<'T> = //'
{ Where : ('T -> bool) option; //'
OrderBy : (('T -> obj) * bool) list; //'
GroupBy : ('T -> obj) …Run Code Online (Sandbox Code Playgroud) type A() =
static member B() = ()
static member B(x) = B() //ERROR: The value or constructor 'B' is not defined
Run Code Online (Sandbox Code Playgroud) 我试图捕获没有引号的引用字符串.我有这个终端
%token <string> STRING
Run Code Online (Sandbox Code Playgroud)
而这个生产
constant:
| QUOTE STRING QUOTE { String($2) }
Run Code Online (Sandbox Code Playgroud)
以及这些词法规则
| '\'' { QUOTE }
| [^ '\'']* { STRING (lexeme lexbuf) } //final regex before eof
Run Code Online (Sandbox Code Playgroud)
它似乎正在解释导致QUOTE单个词汇的所有内容,而不是解析.所以也许我的问题在语法的其他地方 - 不确定.我是以正确的方式来做这件事的吗?在我尝试从字符串中排除引号之前,它解析得很好.
我认为以下词法分析器规则可能存在一些含糊之处
let name = alpha (alpha | digit | '_')*
let identifier = name ('.' name)*
Run Code Online (Sandbox Code Playgroud)
之前的规则如下 STRING
| identifier { ID (lexeme lexbuf) }
Run Code Online (Sandbox Code Playgroud)
有没有办法消除这些歧义,而不包括STRING正则表达式中的引号?
您可以将方法分配给具有匹配类型args的委托:
Func<string, DateTime> f = DateTime.Parse;
Run Code Online (Sandbox Code Playgroud)
您可以将lambda分配给具有协变类型args的委托:
Func<string, object> f = s => DateTime.Parse(s);
Run Code Online (Sandbox Code Playgroud)
但是您不能将方法分配给具有协变类型args的委托:
Func<string, object> f = DateTime.Parse; //ERROR: has the wrong return type
Run Code Online (Sandbox Code Playgroud)
为什么不?
这是接口的合同类的一部分.
[Pure]
public bool IsDirty() {
throw new NotImplementedException();
}
public void Save() {
Contract.Ensures(!this.IsDirty()); //WARNING
throw new NotImplementedException();
}
Run Code Online (Sandbox Code Playgroud)
它正在产生这个警告:
警告CC1036:CodeContracts:在方法'EntityObjectContract.Save'的合同中检测到没有[Pure]的方法'IEntityObject.IsDirty'的调用.
......即使该Pure属性存在.我试过重建,重新打开Visual Studio,但每次都有相同的结果.知道怎么摆脱这个警告吗?我错过了什么吗?
我很好奇F#Seq计算表达式如何实现IEnumerable数据结构.
在GitHub上搜索Sharp.Core/seq.fs以实现yield!(YieldFrom(expr))不成功.
有没有一种方法可以覆盖System.Object的虚拟方法,尤其是ToString在使用对象表达式创建接口类型时?
type INamedObject =
abstract Name : string
let makeNamedObject name =
{ new INamedObject with
member x.Name = name
override x.ToString() = x.Name } //would like to do this, but doesn't work
Run Code Online (Sandbox Code Playgroud) 偶尔,我想从函数中返回一个可变集合作为序列.上传到seq<_>作品,但序列可以被下调和修改(通常不重要).我通常的解决方案是使用wrap-as-a-sequence函数,它产生了以下结果:
let wrap items = Seq.map id
let wrapDict dict = Seq.map ((|KeyValue|) >> snd)
Run Code Online (Sandbox Code Playgroud)
主要是出于好奇(和乐趣),编写这些函数的其他方式是什么,可能是以更惯用,简洁或高效的方式?
是否IEqualityComparer与等式 ( =) 运算符具有相同行为的公开?LanguagePrimitives 模块包含一些:FastGenericEqualityComparer, GenericEqualityComparer, GenericEqualityERComparer. 也许还有其他人?
刚升级到v0.9,我的项目中的几个文件无法编译
错误TS5004:找不到文件:'myfile.ts'.
为了解决问题,我单独编译了它的依赖项,试图缩小问题范围,但它们都编译得很好.所以,我回到了这个档案.Web Essentials的后台编译未显示任何错误.可能是什么导致了这个?
f# ×7
c# ×2
collections ×1
covariance ×1
equality ×1
fslex ×1
fsyacc ×1
generics ×1
ienumerable ×1
parsing ×1
typescript ×1