小编qeh*_*hgt的帖子

邮箱处理器和例外

我想知道,为什么MailboxProcessor处理异常的默认策略只是默默地忽略它们.例如:

let counter =
    MailboxProcessor.Start(fun inbox ->
        let rec loop() =
            async { printfn "waiting for data..."
                    let! data = inbox.Receive()
                    failwith "fail" // simulate throwing of an exception
                    printfn "Got: %d" data
                    return! loop()
            }
        loop ())
()
counter.Post(42)
counter.Post(43)
counter.Post(44)
Async.Sleep 1000 |> Async.RunSynchronously
Run Code Online (Sandbox Code Playgroud)

没有任何反应.程序执行没有致命的停止,或者出现带有"未处理的异常"的消息框.没有.

如果有人使用PostAndReply方法,这种情况会变得更糟:结果是保证死锁.

这种行为有什么理由吗?

f# mailboxprocessor

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

在一个表上组合两个SQL查询

我有一个tableA不同的价值观:

 data
------
 10
 15
 20
 40
 40000
 50000
 60000
Run Code Online (Sandbox Code Playgroud)

此外,我需要获取有关该数据的一些统计信息(我想在一个查询中执行此操作),例如:

select count(data) from tableA where data < 100
union all
select count(data) from tableA  where data >= 100
Run Code Online (Sandbox Code Playgroud)

结果,我收到了

(No column name)
----------------
4
3
Run Code Online (Sandbox Code Playgroud)

但我希望在一行中收到结果,如下所示:

Small | Big
---------
4     | 3 
Run Code Online (Sandbox Code Playgroud)

怎么做?可能吗?

sql sql-server

8
推荐指数
3
解决办法
5854
查看次数

F#"​​for loop"优化

代码示例:

let foo1 (arr : int[]) = 
    for i = 0 to arr.Length-1 do
        arr.[i] <- i

let foo2 (arr : int[]) = 
    for i in [0..arr.Length-1] do
        arr.[i] <- i
Run Code Online (Sandbox Code Playgroud)

我认为这个功能应该相互对应(在性能方面).但如果我们查看IL列表,我们会看到:

第一个功能,15行,没有动态分配,没有try操作员,没有虚拟呼叫:

IL_0000: nop
IL_0001: ldc.i4.0
IL_0002: stloc.0
IL_0003: br.s IL_0011
// loop start (head: IL_0011)
    IL_0005: ldarg.0
    IL_0006: ldloc.0
    IL_0007: ldloc.0
    IL_0008: stelem.any [mscorlib]System.Int32
    IL_000d: ldloc.0
    IL_000e: ldc.i4.1
    IL_000f: add
    IL_0010: stloc.0

    IL_0011: ldloc.0
    IL_0012: ldarg.0
    IL_0013: ldlen
    IL_0014: conv.i4
    IL_0015: blt.s IL_0005
// end loop …
Run Code Online (Sandbox Code Playgroud)

optimization f# for-loop

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

数组切片的奇怪行为

> let a = [| 'a'..'d' |];;
val a : char [] = [|'a'; 'b'; 'c'; 'd'|]
Run Code Online (Sandbox Code Playgroud)

做琐碎的切片:

> a.[1..2], [1..2];;
val it : char [] * int list = ([|'b'; 'c'|], [1; 2])
Run Code Online (Sandbox Code Playgroud)

现在尝试使用空白区域:

> a.[1..0], [1..0];;
val it : char [] * int list = ([||], [])
Run Code Online (Sandbox Code Playgroud)

似乎工作和合理 - 我们有两个空序列.

但它失败了:

> a.[5..0];;
System.OverflowException: Arithmetic operation resulted in an overflow.
   at <StartupCode$FSI_0018>.$FSI_0018.main@()
Stopped due to error
Run Code Online (Sandbox Code Playgroud)

当然,有一种解决方法[| for i in [5..0] -> a.[i] |].但我想念a.[5..0]失败的原因?为什么不直接返回空数组?这种行为有什么理由吗?

arrays f# slice

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

在F#中讨论'灵活类型'

代码的一小部分,以突出问题:

open System.IO

let do_smth i (stm : #System.IO.Stream) =  // val do_smth : 'a -> #Stream -> unit
    (*....*)
    ()

type SomeOps = SomeOps with
    static member op (i : int) = do_smth i

let test_currying i = do_smth i            // val test_currying : 'a -> (Stream -> unit)
                                           // NB: Stream, not #Stream
let main() = 
    use stm = new System.IO.MemoryStream()
    test_currying 42 stm  // OK, upcasted to Stream somehow
    SomeOps.op 42 stm     // compiler error!
Run Code Online (Sandbox Code Playgroud)

有人可以解释一下,为什么编译器的行为在最后两行中如此不同?为什么我们#Stream …

f# types currying

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

如何在F#中声明循环相关的抽象类

考虑两个抽象类alpha和beta:

[<AbstractClass>]  
type alpha () =
    abstract member foo: beta->beta

[<AbstractClass>] 
and beta () = //***
    abstract member bar: alpha
Run Code Online (Sandbox Code Playgroud)

如果我尝试编译,我得到一个错误,在***指示的行上:

error FS0010: Unexpected keyword 'and' in interaction
Run Code Online (Sandbox Code Playgroud)

如果我写:

[<AbstractClass>]  
type alpha () =
    abstract member foo: beta->beta

and beta () =
    abstract member bar: alpha
Run Code Online (Sandbox Code Playgroud)

然后我得到:

error FS0365: No implementation was given for 'abstract member beta.bar : alpha'
Run Code Online (Sandbox Code Playgroud)

以及我应该添加AbstractClass属性的提示

那么我如何声明循环定义的抽象类?

.net f# abstract-class circular-dependency circular-reference

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

自动枚举序列

是否有标准函数来枚举一个像Python的enumerate()一样工作的F#序列?

从头开始编写非常容易:

let enumerate (sq : seq<'T>) = seq {
    let rec loop (e : IEnumerator<'T>) index = seq {
        if e.MoveNext() then 
            yield (index, e.Current)
            yield! loop e (index+1) 
    }

    use enum = sq.GetEnumerator()
    yield! loop enum 0
    }
Run Code Online (Sandbox Code Playgroud)

但我不想重新发明轮子.

PS:还有,我试过了

let seasons = ["Spring"; "Summer"; "Fall"; "Winter"]
for x in Seq.zip [0..100000] seasons do
    printfn "%A" x
Run Code Online (Sandbox Code Playgroud)

但这[0..10000]部分看起来很难看.

f# sequences

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

如何在struct/class中获取有关"当前类型"的信息?

是否有可能获得"当前的类型struct" struct?例如,我想做这样的事情:

struct foobar {
  int x, y;

  bool operator==(const THIS_TYPE& other) const  /*  What should I put here instead of THIS_TYPE? */
  {
    return x==other.x && y==other.y;
  }
}
Run Code Online (Sandbox Code Playgroud)

我试着这样做:

struct foobar {
  int x, y;

  template<typename T>
  bool operator==(const T& t) const
  {
    decltype (*this)& other = t; /* We can use `this` here, so we can get "current type"*/
    return x==other.x && y==other.y;
  }
}
Run Code Online (Sandbox Code Playgroud)

但它看起来很难看,需要支持最新的C++标准,而MSVC不能编译它(它会因"内部错误"而崩溃).

实际上,我只是想编写一些预处理器宏来自动生成如下函数operator==:

struct foobar {
  int x, …
Run Code Online (Sandbox Code Playgroud)

c++ macros

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

从不同的线程写入boost :: asio socket

在我们的应用程序中,我们使用Boost库(和ASIO进行网络通信).

最近,我们发现如果我们通过相同的套接字从不同的线程发送数据,我们的客户端应用程序就会接收数据.

小测试突出问题:

#include <stdio.h>
#include <boost/thread.hpp>
#include <boost/asio.hpp>

void send_routine(boost::shared_ptr<boost::asio::ip::tcp::socket> s, char c)
{
  std::vector<char> data(15000, c);
  data.push_back('\n');

  for (int i=0; i<1000; i++)
    boost::asio::write(*s, boost::asio::buffer(&data[0], data.size()));
}


int main()
{
  using namespace boost::asio;
  using namespace boost::asio::ip;

  try {
    io_service io_service;
    io_service::work work(io_service);

    const char* host = "localhost";
    const char* service_name = "18000";

    tcp::resolver resolver(io_service);
    tcp::resolver::query query(tcp::v4(), host, service_name);
    tcp::resolver::iterator iterator = resolver.resolve(query);

    auto socket = boost::shared_ptr<tcp::socket>(new tcp::socket(io_service));
    socket->connect(*iterator);

    boost::thread t1(send_routine, socket, 'A');
    boost::thread t2(send_routine, socket, 'B');
    boost::thread t3(send_routine, socket, …
Run Code Online (Sandbox Code Playgroud)

c++ sockets multithreading boost boost-asio

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