小编Ove*_*ive的帖子

在F#中使用私有构造函数创建一个类

我想创建一个只有一个私有构造函数的类.现在我知道如何在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)

f# constructor private class

22
推荐指数
1
解决办法
1949
查看次数

关于OleDb连接打开的SEHException

我正在开发一个简化日志记录的小应用程序,它通过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)

c# oledb ms-access f#

13
推荐指数
1
解决办法
1607
查看次数

为什么这个F#代码比C#代码慢?

我正在解决项目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)

c# f#

12
推荐指数
1
解决办法
655
查看次数

折叠选项列表

给出一个列表[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)

f# fold optional

11
推荐指数
2
解决办法
510
查看次数

覆盖等于和类型转换

在下面的示例中,第三个评估返回false,一切都很好,但第四个示例返回true ..
我不太明白这是如何工作的,但默认情况下Object.Equals比较两个引用以实现对象相等,并且看到as abboth都指向一个唯一的一个字符串的实例,这应该返回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)

c# polymorphism equality unary-operator

8
推荐指数
1
解决办法
661
查看次数

使用continuation在F#中处理树

我试图理解延续是如何工作的,我在本书中遇到了这个例子,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但我不太明白这一切是如何组合在一起的,我不得不承认,当我试图解决这个问题时,我有点头晕.

lambda continuations f#

6
推荐指数
3
解决办法
572
查看次数

控制平衡括号

假设我们有一个包含不同括号的字符串(在此上下文中用括号表示(,[{),字符串也可以包含其他类似的内容,{[balanced(parenthesis)]}但其余内容将在很大程度上被忽略.是否可以使用正则表达式来控制所有不同的括号:

  1. "关闭",即每个"开口"括号与"结束"括号匹配,并且
  2. 在字符串中的正确位置?

.net c# regex

5
推荐指数
1
解决办法
842
查看次数

堆栈溢出和递归序列表达式 F#

我有一个像这样的序列表达式:

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 个斐波那契数,每个递归调用都需要返回到调用者,最终将其自身“折叠”到序列中。这里是否有某种优化在幕后进行?

recursion f# tail-recursion fibonacci lazy-sequences

5
推荐指数
1
解决办法
858
查看次数

Tuple.Create in F#

我注意到System.Tuple.CreateF#中方法的一个非常奇怪的行为.查看MSDN文档时,它表明返回类型是System.Tuple<T>.但是在F#中使用此方法时除了Tuple.Create(T)将返回所有重载'T1 * 'T2.显然调用Tuple<T>构造函数将返回Tuple<T>.但我不明白Tuple.CreateF#的返回类型是如何不同的.

.net f# tuples base-class-library

4
推荐指数
1
解决办法
331
查看次数

无法在F#中创建列表文字

我有以下几种类型

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)

我得到一个编译时错误,说:

这不是有效的常量表达式或自定义属性值

我无法弄清楚这里有什么问题.

f# compile-time-constant constant-expression

4
推荐指数
1
解决办法
439
查看次数