我想创建一个只有一个私有构造函数的类.现在我知道如何在C#中做到这一点,但我无法弄清楚如何在F#中做到这一点.
基本上这就是我想在F#中做的事情:
/// <summary>
/// A valid string is a string of 50 characters or less that contains only letters of the latin alphabet.
/// </summary>
public sealed class ValidString {
private readonly string _value;
private ValidString(string value) {
_value = value;
}
public string Value { get { return _value; } }
public static bool TryParse(string input, out ValidString validStr) {
bool valid = input.Length <= 50 && input.All(Char.IsLetter);
validStr = valid ? new ValidString(input) : null; …Run Code Online (Sandbox Code Playgroud) 我正在开发一个简化日志记录的小应用程序,它通过OleDB向MS Access数据库添加一些输入来实现.
let private conn = new OleDbConnection(connectionString)
let private submitCmd date wins =
let cmd = new OleDbCommand("INSERT INTO ArenaStats ([Date], [Wins]) VALUES (@Date, @Wins)",
Connection = conn, CommandType = CommandType.Text)
["@Date", box date; "@Wins", box wins]
|> List.iter (cmd.Parameters.AddWithValue >> ignore)
cmd
let private submit date wins =
try
conn.Open()
(submitCmd date wins).ExecuteNonQuery() |> ignore
finally
conn.Close()
[<CompiledName "AddEntry">]
let addEntry(date:DateTime, wins:int) =
submit date wins
Run Code Online (Sandbox Code Playgroud)
现在通过FSI进行测试就像预期的那样.但是,当我从C#WPF项目中使用此API时,它会抛出一个SEHExceptionat conn.Open().我真的很想知道为什么会这样.
编辑
正如所建议的那样,我也尝试在C#中实现相同的代码,并且在同一个项目中,它会在同一个地方抛出相同的异常,但我发布下面的代码以供参考.
class MsAccessDatabase : IArenaWinsDatabase { …Run Code Online (Sandbox Code Playgroud) 我正在解决项目Euler问题(在我学习C#之前做了23个第一个问题)而且我对我解决问题5的性能低下来感到困惑.
其内容如下:
2520是可以除以1到10中的每个数字而没有任何余数的最小数字.
可以被1到20的所有数字整除的最小正数是多少?
现在我的C#令人难以置信的原始蛮力解决方案在大约25秒内完成了这个问题.
var numbers = Enumerable.Range(1, 20);
int start = 1;
int result;
while (true)
{
if (numbers.All(n => start % n == 0))
{
result = start;
break;
}
start++;
}
Run Code Online (Sandbox Code Playgroud)
现在我的F#解决方案也使用暴力强制,但至少它会有更多的歧视,所以它"应该"在我的脑海中运行得更快,但它在约45秒时出现,所以它几乎是C#的两倍慢.
let p5BruteForce =
let divisors = List.toSeq ([3..20] |> List.rev)
let isDivOneToTwenty n =
let dividesBy =
divisors |> Seq.takeWhile(fun x -> n % x = 0)
Seq.length dividesBy = Seq.length divisors
let findNum n =
let rec loop n =
match isDivOneToTwenty n …Run Code Online (Sandbox Code Playgroud) 给出一个列表[Some 1; Some 2; Some 3]我想要一个输出Some 6.鉴于列表[Some 1; None]应该产生None.
但我发现它比我想象的要干净得多.
我能想到的最好的就是这个
let someNums = [Some 1; Some 2; Some 3]
someNums
|> List.reduce (fun st v ->
Option.bind (fun x ->
Option.map (fun y -> x + y) st) v )
Run Code Online (Sandbox Code Playgroud) 在下面的示例中,第三个评估返回false,一切都很好,但第四个示例返回true ..
我不太明白这是如何工作的,但默认情况下Object.Equals比较两个引用以实现对象相等,并且看到as a和bboth都指向一个唯一的一个字符串的实例,这应该返回false,它在第三个例子中但不在第四个例子中.
现在我理解为什么它在第二个例子中返回true,因为.Equals()在字符串类中重写了方法,但在第四个例子中,我们将此字符串作为对象进行转换.
所以不会Object.Equals在这种情况下打电话吗?
static void Main()
{
// Create two equal but distinct strings
string a = new string(new char[] {'h', 'e', 'l', 'l', 'o'});
string b = new string(new char[] {'h', 'e', 'l', 'l', 'o'});
Console.WriteLine (a == b); // Returns true
Console.WriteLine (a.Equals(b)); // Returns true
// Now let's see what happens with the same tests but
// with variables of type object
object c = …Run Code Online (Sandbox Code Playgroud) 我试图理解延续是如何工作的,我在本书中遇到了这个例子,Tomas Petricek与Jon Skeet的真实世界功能编程.但这确实让我头疼,所以我必须要求一些详细的帮助..
type IntTree =
| Leaf of int
| Node of IntTree * IntTree
let rec sumTreeCont tree cont =
match tree with
| Leaf(n) -> cont(n)
| Node(left, right) ->
sumTreeCont left (fun leftSum ->
sumTreeCont right (fun rightSum ->
cont(leftSum + rightSum)))
Run Code Online (Sandbox Code Playgroud)
好的,这就是我能够弄清楚自己......在第二个分支中,我们首先处理节点的左侧并传递一个lambda.此拉姆达将实例的封闭类具有两个字段,right: IntTree并且cont: (int -> 'a)这将是由基础案例被调用.但是,似乎"内在的lambda"捕获leftSum但我不太明白这一切是如何组合在一起的,我不得不承认,当我试图解决这个问题时,我有点头晕.
假设我们有一个包含不同括号的字符串(在此上下文中用括号表示(,[和{),字符串也可以包含其他类似的内容,{[balanced(parenthesis)]}但其余内容将在很大程度上被忽略.是否可以使用正则表达式来控制所有不同的括号:
我有一个像这样的序列表达式:
let fibSeq =
let rec fibSeq' a b =
seq { yield a
yield! fibSeq' b (a + b) }
fibSeq' 1 1
Run Code Online (Sandbox Code Playgroud)
现在,即使对于很大的数字,这也不会产生堆栈溢出。我想知道为什么,在我看来,要使用此序列表达式生成n 个斐波那契数,每个递归调用都需要返回到调用者,最终将其自身“折叠”到序列中。这里是否有某种优化在幕后进行?
我注意到System.Tuple.CreateF#中方法的一个非常奇怪的行为.查看MSDN文档时,它表明返回类型是System.Tuple<T>.但是在F#中使用此方法时除了Tuple.Create(T)将返回所有重载'T1 * 'T2.显然调用Tuple<T>构造函数将返回Tuple<T>.但我不明白Tuple.CreateF#的返回类型是如何不同的.
我有以下几种类型
type StatusCode =
| OK = 200
| NoContent = 204
| MovedTemp = 301
| MovedPerm = 302
| SeeOther = 303
| NotModified = 304
| NotFound = 404
| ServerError = 500
[<Literal>]
let NoBodyAllowedStatusCodes = [StatusCode.NoContent; StatusCode.NotModified]
Run Code Online (Sandbox Code Playgroud)
我得到一个编译时错误,说:
这不是有效的常量表达式或自定义属性值
我无法弄清楚这里有什么问题.