在F#monad中,如果你说let!
,编译器会将其转换为Bind
你在monad构建器上定义的成员.
现在我看到有一个Query monads,如MSDN所示,你可以说:
query {
for student in db.Student do
select student
count
}
Run Code Online (Sandbox Code Playgroud)
和select
和count
,例如,将被翻译到QueryBuilder
成员Linq.QueryBuilder.Select和Linq.QueryBuilder.Count
.
我的问题是,关键字映射到成员是否已硬连接到F#编译器,还是可扩展?例如,我可以这样说:
FooMonadBuilder() {
bar
}
Run Code Online (Sandbox Code Playgroud)
并以某种方式告诉F#编译器bar
映射到一个FooMonadBuilder.Bar()
方法?
我想定义一个PHP 7函数,它接受混合类型的参数.(我想要的是相当于C#中的泛型类型参数;如果有更好的方法在PHP 7中模拟它,请告诉我.)
我的代码如下.
<?php
declare (strict_types = 1);
function test (mixed $s) : mixed {
return $s;
}
// Works
echo gettype ('hello');
// Does not work
echo test ('hello');
?>
Run Code Online (Sandbox Code Playgroud)
当我运行此代码时,我得到以下内容.
Fatal error: Uncaught TypeError: Argument 1 passed to test() must be an instance of mixed, string given, called in mixed.php on line 11 and defined in mixed.php:4
Stack trace:
#0 mixed.php(11): test('hello')
#1 {main}
thrown in mixed.php on line 4
Run Code Online (Sandbox Code Playgroud)
如果我注释掉对test()的调用,代码运行正常,所以显然我至少可以在函数声明中使用混合参数类型.
我知道内置的PHP函数(如gettype())可以采用混合参数,但我不知道它们是否在内部使用严格的类型.
我看到"混合"在PHP 文档中也被用作伪类型,所以我可能误解了"混合"作为PHP关键字的目的,但我在这里看到的至少暗示我这是合法的关键词.我只是以一种不适合的方式使用它吗?
最后,我意识到我可以通过简单地不指定参数类型来规避所有这些,但我希望通过指定所有参数和返回类型来保持一致.
谢谢,如果我能提供任何其他信息,请告诉我.
我有一个函数,它接受一个object类型的参数,需要将它向下转换为option<obj>
.
member s.Bind(x : obj, rest) =
let x = x :?> Option<obj>
Run Code Online (Sandbox Code Playgroud)
如果我传递(例如)Option<string>
as x
,则最后一行抛出异常:无法转换类型为"Microsoft.FSharp.Core.FSharpOption'1 [System.String]"的对象以键入"Microsoft.FSharp.Core.FSharpOption" 1 [System.Object的]".
或者,如果我尝试进行类型测试:
member s.Bind(x : obj, rest) =
match x with
| :? option<obj> as x1 -> ... // Do stuff with x1
| _ -> failwith "Invalid type"
Run Code Online (Sandbox Code Playgroud)
然后x
从不匹配option<obj>
.
为了使这项工作,我当前必须指定选项包含的类型(例如,如果函数被传递option<string>
,并且我将参数向下转换为而不是option<obj>
,函数可以工作.
有没有一种方法可以将参数向下转换为option<obj>
不指定选项包含的类型?我试过了option<_>
,option<#obj>
并且option<'a>
得到了相同的结果.
作为背景,参数需要是类型的,obj
因为我正在为monad编写接口,因此Bind需要根据实现接口的monad绑定不同类型的值.这个特殊的monad是一个延续monad,所以它只是想确定参数是否Some(x)
存在None
,然后传递x
给休息.(我需要接口的原因是因为我正在编写一个monad转换器,我需要一种方法告诉它它的参数monad实现bind和return.) …
我正在试验F#中的C++ AMP库,作为使用GPU并行工作的一种方式.但是,我得到的结果似乎并不直观.
在C++中,我创建了一个带有一个函数的库,它使用AMP对数组中的所有数字进行平方:
extern "C" __declspec ( dllexport ) void _stdcall square_array(double* arr, int n)
{
// Create a view over the data on the CPU
array_view<double,1> dataView(n, &arr[0]);
// Run code on the GPU
parallel_for_each(dataView.extent, [=] (index<1> idx) restrict(amp)
{
dataView[idx] = dataView[idx] * dataView[idx];
});
// Copy data from GPU to CPU
dataView.synchronize();
}
Run Code Online (Sandbox Code Playgroud)
(代码改编自Igor Ostrovsky 在MSDN上的博客.)
然后我编写了以下F#来比较任务并行库(TPL)和AMP:
// Print the time needed to run the given function
let time f =
let s = new …
Run Code Online (Sandbox Code Playgroud) 我有一个F#类库,其中包含使用NuGet安装的"xUnit.net"和"xUnit.net Runners"软件包.我有以下代码:
module XUnitTest
open Xunit
[<Fact>]
let Test () =
do Assert.True (1 = 2)
()
Run Code Online (Sandbox Code Playgroud)
当我运行xUnit GUI(NuGet添加到(projectdirectory)\ packages\xunit.runners.1.9.1\tools的xunit.gui.clr4.exe)并加载由该项目构建的程序集时,Test()方法出现,并在我按预期运行时失败.
但是,我无法让测试出现在VS 2012的测试资源管理器中,无论我重建,重启等多少次.如果我单击全部运行,弹出构建输出窗口但没有其他任何事情发生.
为此,我还安装了xUnit.net Extensions,但我不认为它们对我正在尝试做的事情是必要的.这也没有帮助.
如果我能提供更多信息,请告诉我,谢谢你的阅读!
我看到的典型Pause monad实现看起来像这样(基于来自Friendly F#by Giulia Costantini和Giuseppe Maggiore的第5章).
open System
type Process<'a> = unit -> 'a Step
and Step<'a> =
| Continue of 'a
| Paused of 'a Process
type PauseMonad () =
member this.Return x = fun () -> Continue x
member this.ReturnFrom x = x
member this.Bind (result, rest) =
fun () ->
match result () with
| Continue x -> rest x ()
| Paused p -> Paused (this.Bind (p, rest))
let yield_ () =
fun () ->
Paused …
Run Code Online (Sandbox Code Playgroud)