小编Dan*_*iel的帖子

Enum(flags)成员由其他成员组成

[<Flags>]
type LikeMatch =
    | None  = 0
    | Start = 1
    | End   = 2
    | All   = Start ||| End //ERROR: Unexpected identifier in union case
Run Code Online (Sandbox Code Playgroud)

我也尝试用枚举类型对成员进行限定.有没有办法在F#中做到这一点?

f#

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

可选择采用序列中的第一项

我需要一个类似的函数Seq.head,但是None当序列为空时返回而不是抛出异常,即seq<'T> -> 'T option.

有很多方法可以做到这一点.这里有几个:

let items = Seq.init 10 id
let a = Seq.tryFind (fun _ -> true) items
let b = Seq.tryPick Some items
let c = if Seq.isEmpty items then None else Some (Seq.head items)
let d = 
  use e = items.GetEnumerator()
  if e.MoveNext() then Some e.Current
  else None
Run Code Online (Sandbox Code Playgroud)

b是我使用的那个.两个问题:

  1. 是否有一种特别惯用的方法呢?
  2. 由于没有内置Seq.tryHead函数,这是否表明这不是必需的,是不常见的,或者在没有函数的情况下更好地实现?

UPDATE

tryHead已添加到F#4.0的标准库中.

f# idioms sequence

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

为什么None表示为null?

CompilationRepresentationFlags.UseNullAsTrueValue 可以用来

允许使用null作为歧视联盟中的否定鉴别器的表示

Option.None 是这方面最突出的例子.

为什么这有用?如何检查空检查比检查联合情况(生成的Tag属性)的传统机制更好?

它可能导致意外的行为:

Some(1).ToString() //"Some(1)"
None.ToString()    //NullReferenceException
Run Code Online (Sandbox Code Playgroud)

编辑

我测试了Jack的断言,即与null相比,而不是静态只读字段更快.

[<CompilationRepresentation(CompilationRepresentationFlags.UseNullAsTrueValue)>]
type T<'T> =
  | Z
  | X of 'T

let t = Z
Run Code Online (Sandbox Code Playgroud)

使用ILSpy,我可以看到t编译为null(如预期的那样):

public static Test.T<a> t<a>()
{
    return null;
}
Run Code Online (Sandbox Code Playgroud)

考试:

let mutable i = 0
for _ in 1 .. 10000000 do
  match t with
  | Z -> i <- i + 1
  | _ -> ()
Run Code Online (Sandbox Code Playgroud)

结果:

Real:00:00:00.036,CPU:00:00:00.046,GC gen0:0,gen1:0,gen2:0

如果CompilationRepresentation删除该属性,则t成为静态只读字段:

public static Test.T<a> t<a>() …
Run Code Online (Sandbox Code Playgroud)

f# discriminated-union

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

什么是实验性功能"索引成员"?

在新的Roslyn预览网站上,它提到了能够尝试潜在的语言功能,并列出了三个这样的功能.

截图

我之前听过的前两个(例如这里),但我无法从代码示例中找出"索引成员"是什么.任何人都可以根据其他来源或代码示例解释这些是什么吗?(它没有价值$x,不是C#5中的有效标识符.)

更新 - 根据Roslyn功能状态页面,此功能已被撤消.

c# roslyn c#-6.0

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

传播可选参数

以下代码无法编译.

type A(?arg) =
  member __.Arg : string option = arg

type B(?arg) =
  inherit A(arg) //ERROR expected type string but has type 'a option
Run Code Online (Sandbox Code Playgroud)

我假设这是因为必须提供选项的基础类型的实例,并且编译器处理传递Some/ None基于语法.

假设我的假设已被正确假设,是否有解决方法?是否可以传播可选参数?

inheritance f# optional-arguments

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

引用列的统计信息是否会阻止该列被删除?

我正在尝试一个非常简单的drop column陈述:

alter table MyTable drop column MyColumn
Run Code Online (Sandbox Code Playgroud)

并接受几个错误

消息5074,级别16,状态1,行1
统计信息'_dta_stat_1268251623_3_2'取决于列'MyColumn'.

最后是

消息4922,级别16,状态9,行1
ALTER TABLE DROP COLUMN MyColumn失败,因为一个或多个对象访问此列.

我不认为统计数据会阻止列被删除.他们呢?如果是这样,因为这些显然是自动创建的统计信息,我不能依赖于同一数据库的多个副本中的名称相同,那么我怎样才能在升级脚本中删除所有这些统计信息以在不同的数据库上执行?

sql-server ddl sql-server-2005

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

两个层次结构的单向同步

我希望编写一个算法来同步两个层次结构.这些结构可以是对象图,存储在关系数据库表中的数据等(即使是两个不同的结构,只要它们具有可比较的密钥).同步将是单向的,即一个结构将是原型,另一个将被修改以匹配.

假设我们有一个sync功能.它需要接受以下内容:

  1. objA - 原型
  2. objB - 要修改的对象
  3. keyA - 密钥生成功能 objA
  4. keyB - 密钥生成功能 objB
  5. addB- 创建一个函数objB(返回新的id objB)
  6. setB - 更新功能 objB
  7. remB - 删除功能 objB
  8. parB- objB父级的id - 传递给addB上下文

所以我们有这个:

let sync (objA:'a) (objB:'b) (keyA:'a -> 'k) (keyB:'b -> 'k)
         (addB:'p * 'a -> 'p) (setB:'a * 'b -> unit) (remB:'b -> unit) 
         (parB:'p) = ...
Run Code Online (Sandbox Code Playgroud)

现在这里我遇到了麻烦.'a并且'b是分层的,因此函数需要知道哪些属性'a'b它应该遍历(一旦它比较它们的键并决定它们到目前为止匹配并且应该进一步遍历).对于这些"子"属性,它需要传递给同步的所有相同参数,但是它们各自的类型.

这是显而易见的,这是一个数据结构问题.如何将这些信息链接在一起,以便根对象可以传递给sync它,并且它可以向下遍历图形?我最初的想法是将所有参数合并到一个类中,该类具有子属性(属于 …

merge f# object-graph data-structures

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

每行禁用编译器警告

是否可以禁用特定行的编译器警告?

在C#中,这有效:

[Obsolete]
class Old { }

#pragma warning disable 612
    var oldWithoutWarning = new Old();
#pragma warning restore 612
    var oldWithWarning = new Old();
Run Code Online (Sandbox Code Playgroud)

这对于禁用不完整模式匹配警告非常有用,尤其是当函数接受DU的特定情况时.

f# compiler-warnings

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

解决枚举上不完整的模式匹配问题

在模式匹配时,是否有任何创造性的方法可以解决.NET的"弱"枚举问题?我希望它们的功能与DU类似.这是我目前处理它的方式.有更好的想法吗?

[<RequireQualifiedAccess>]
module Enum =
  let unexpected<'a, 'b, 'c when 'a : enum<'b>> (value:'a) : 'c = //'
    failwithf "Unexpected enum member: %A: %A" typeof<'a> value //'

match value with
| ConsoleSpecialKey.ControlC -> ()
| ConsoleSpecialKey.ControlBreak -> ()
| _ -> Enum.unexpected value //without this, gives "incomplete pattern matches" warning
Run Code Online (Sandbox Code Playgroud)

enums f# pattern-matching

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

如何在F#中创建同步函数的异步版本?

您可以使用哪些不同的技术在F#中创建Async <'T>的实例?

我看到Web客户端/请求和文件流有很多扩展方法,但是如果我想编写自己的异步计算提供程序,我将如何编写AsyncDoSomething同步DoSomething函数的那些版本?

我知道,你可以使用相同签名的委托来包装原有的功能,然后用Async.FromBeginEndBeginInvokeEndInvoke方法:

open System

let del : Func<int> = new Func<int>(fun () -> 42)
let delAsync = async {
    let! res = Async.FromBeginEnd(del.BeginInvoke, del.EndInvoke)
    printfn "result was %d" res
}

Async.Start delAsync
Run Code Online (Sandbox Code Playgroud)

但这感觉有点强迫,它似乎不是'F#方式',因为你必须使用在C#或VB中定义的代理(其中有很多System.ActionSystem.Func变体可供选择)因为F#代表不要支持BeginInvokeEndInvoke方法.

有没有人有一个列表,你可以在F#中编写同步函数的异步版本的不同方法?

提前谢谢了!

f# asynchronous functional-programming

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