小编Dan*_*iel的帖子

Tupled函数组合

我很好奇为什么会这样

let f = (fun a b -> a, b) >> obj.Equals
Run Code Online (Sandbox Code Playgroud)

给出了错误

没有名为'Equals'的可访问成员或对象构造函数需要1个参数

但这很有效

let f = (fun a -> a, a) >> obj.Equals
Run Code Online (Sandbox Code Playgroud)

f# function-composition

3
推荐指数
1
解决办法
137
查看次数

F#函数具有多态(在OO意义上)返回类型

是否可以让函数返回多个类型,只要它们共享一个公共基类,而不转换每个返回值?

例如:

[<AbstractClass>]
type A() = 
  abstract Do : unit -> unit

type B() =
  inherit A()
  override x.Do() = ()

type C() =
  inherit A()
  override x.Do() = ()

let getA i : A =
  if i = 0 then new B() else new C() //Error: This expression was expected to have type A but here has type B
Run Code Online (Sandbox Code Playgroud)

f#

2
推荐指数
1
解决办法
520
查看次数

未知需要类型注释或强制转换

我知道我必须遗漏一些非常明显的东西.B.GetInstance().Call()生成错误:根据此程序点之前的信息查找不确定类型的对象.在此程序点之前可能需要类型注释来约束对象的类型.这可以允许解析查找.

我正在使用v1.9.9.9.

type A() =
    member x.Call() = B.GetInstance().Call()

and B() =
    static member GetInstance() = new B()
    member x.Call() = ()
Run Code Online (Sandbox Code Playgroud)

我刚刚发现这个有效: (B.GetInstance() :> B).Call()

知道为什么演员是必要的吗?

f# type-inference

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

重写简单的C#嵌套类

在F#中实现这个嵌套类的功能的优雅方法是什么?

  private class Aliaser {
     private int _count;
     internal Aliaser() { }
     internal string GetNextAlias() {
        return "t" + (_count++).ToString();
     }
  }
Run Code Online (Sandbox Code Playgroud)

这是我的第一次尝试,但感觉应该有一个性感的单行为此:

let aliases = (Seq.initInfinite (sprintf "t%d")).GetEnumerator()

let getNextAlias() = 
    aliases.MoveNext() |> ignore
    aliases.Current
Run Code Online (Sandbox Code Playgroud)

f#

2
推荐指数
1
解决办法
896
查看次数

类型(单位 - >单位)的函数是否可以在F#中静态解析类型参数?

为什么不允许这样做?

type Foo() =
    static member Bar() = ()

let inline bar<^a>() = //ERROR: unexpected infix operator in pattern
    (^a : (static member Bar : unit -> unit)())

//Hypothetical usage: let _ = bar<Foo>()
Run Code Online (Sandbox Code Playgroud)

......但是这样可以吗?

type Foo() =
    static member Bar() = new Foo()

let inline bar() : ^a =
    (^a : (static member Bar : unit -> ^a)())

let x : Foo = bar()
Run Code Online (Sandbox Code Playgroud)

具有静态解析类型参数的函数是否需要返回已解析类型的实例?

f# inline

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

通用参数的空列表

规范的第15.3节提到了< >具有插入空白的序列是允许的形式.它表示一个通用参数的空列表,它允许以下奇怪.

type A() = class end
let a = new A< >()
Run Code Online (Sandbox Code Playgroud)

为什么允许这样做?由于泛型类型可以在省略类型args的情况下实例化,这是一种类型检查排序的优化吗?

f#

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

为什么活动模式需要特殊语法?

如果普通函数可以用作模式,则可以节省必须编写琐碎的活动模式,如

let (|NotEmpty|_|) s = Seq.tryPick Some s
Run Code Online (Sandbox Code Playgroud)

并且假设允许

let s = seq []
match s with
| Seq.tryPick Some -> ...
| _ -> //empty
Run Code Online (Sandbox Code Playgroud)

这将使函数更具可重用性,无需使用匹配的"模式化"函数:

let f x = if x then Some() else None
let (|F|_|) = f
Run Code Online (Sandbox Code Playgroud)

我知道活动模式可以被称为函数,因此可以通过定义模式来简化前面的示例.但是,放弃特殊模式语法简化了这一点.

特殊语法的原因是什么?

编辑

在下文中,活动模式会影响文字.

[<Literal>]
let X = 1
let (|X|_|) x = if x = 0 then Some() else None

match 0 with //returns true
| X -> true
| _ -> false
Run Code Online (Sandbox Code Playgroud)

为什么在模式中函数调用也不起作用?

编辑2

我发现了一个模棱两可的场景 …

f# pattern-matching active-pattern

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

拦截ESC而不从缓冲区中删除其他按键

我有一个控制台应用程序,提示用户多个输入.我希望用户能够在任何提示取消操作后按下escape.

就像是:

if (Console.ReadKey().Key != ConsoleKey.Escape) {
  string input = Console.ReadLine();
  ...
}
Run Code Online (Sandbox Code Playgroud)

但问题是,如果按下除了escape之外的键,它将不是输入的一部分(从中返回ReadLine).

有没有办法"偷看"下一个键,否则这样做?

.net c# console pinvoke

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

如何匹配空元组列表?

以下函数在我尝试匹配空列表时给出了编译错误:

let rec tuplesToList (acc: int list) (remaining: int*int list) =
    match remaining with
    | [] -> acc
    | (a, b) :: tail -> tuplesToList (a :: b :: acc)
Run Code Online (Sandbox Code Playgroud)

错误是:

This expression was expected to have type int * int list but here has type 'a list
Run Code Online (Sandbox Code Playgroud)

remaining一个简单的ints 列表而不是元组时,这很好用.如何匹配空元组列表?

f# tuples list

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