我很好奇为什么会这样
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) 是否可以让函数返回多个类型,只要它们共享一个公共基类,而不转换每个返回值?
例如:
[<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) 我知道我必须遗漏一些非常明显的东西.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#中实现这个嵌套类的功能的优雅方法是什么?
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) 为什么不允许这样做?
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)
具有静态解析类型参数的函数是否需要返回已解析类型的实例?
规范的第15.3节提到了< >具有插入空白的序列是允许的形式.它表示一个通用参数的空列表,它允许以下奇怪.
type A() = class end
let a = new A< >()
Run Code Online (Sandbox Code Playgroud)
为什么允许这样做?由于泛型类型可以在省略类型args的情况下实例化,这是一种类型检查排序的优化吗?
如果普通函数可以用作模式,则可以节省必须编写琐碎的活动模式,如
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)
为什么在模式中函数调用也不起作用?
我发现了一个模棱两可的场景 …
我有一个控制台应用程序,提示用户多个输入.我希望用户能够在任何提示取消操作后按下escape.
就像是:
if (Console.ReadKey().Key != ConsoleKey.Escape) {
string input = Console.ReadLine();
...
}
Run Code Online (Sandbox Code Playgroud)
但问题是,如果按下除了escape之外的键,它将不是输入的一部分(从中返回ReadLine).
有没有办法"偷看"下一个键,否则这样做?
以下函数在我尝试匹配空列表时给出了编译错误:
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 列表而不是元组时,这很好用.如何匹配空元组列表?