我一直在做F#开发一段时间,我喜欢它.然而,我知道在F#中不存在的一个流行语是更高级的类型.我已经阅读了关于高等类型的材料,我想我理解他们的定义.我只是不确定他们为什么有用.有人可以在Scala或Haskell中提供一些高级类型易于使用的示例吗?这需要F#中的变通方法?同样对于这些示例,如果没有更高级的类型(或F#中反之亦然),解决方法是什么?也许我只是习惯于解决它,我没有注意到这个功能的缺席.
(我认为)我得到的不是myList |> List.map f或myList |> Seq.map f |> Seq.toList更高的kinded类型允许你简单地写myList |> map f,它将返回一个List.这很好(假设它是正确的),但似乎有点小?(并且不能简单地通过允许函数重载来完成?)我通常转换为Seq无论如何然后我可以转换为我想要的任何东西.再说一次,也许我只是习惯于解决它.但有没有任何一个例子,高级类型的类型真的可以节省你的击键或类型安全?
鉴于CLR泛型实现支持比JVM更多的功能,例如具体化,而JVM的泛型仅仅是Java "编译器技巧",为什么在F#中不可能使用更高级的类型但在Scala中可能?CLR泛型实现是否会以某种方式阻碍事物的发生,而JVM缺少一个允许您进一步超出设计者的意图; 有点像动态语言让你做一个强类型编译器不可能的技巧?
我有这个haskell文件,用ghc -O2(ghc 7.4.1)编译,在我的机器上花了1.65秒
import Data.Bits
main = do
print $ length $ filter (\i -> i .&. (shift 1 (i `mod` 4)) /= 0) [0..123456789]
Run Code Online (Sandbox Code Playgroud)
用gcc -O2(gcc 4.6.3)编译的C中的相同算法在0.18秒内运行.
#include <stdio.h>
void main() {
int count = 0;
const int max = 123456789;
int i;
for (i = 0; i < max; ++i)
if ((i & (1 << i % 4)) != 0)
++count;
printf("count: %d\n", count);
}
Run Code Online (Sandbox Code Playgroud)
更新
我认为它可能会变Data.Bits得很慢,但令人惊讶的是,如果我移除了移位而只是做直mod,它实际上在5.6秒时运行得更慢!?!
import …Run Code Online (Sandbox Code Playgroud) 所以我的要求是让我的函数等待event Action<T>来自另一个类和另一个线程的第一个实例,并在我的线程上处理它,允许等待被超时或中断CancellationToken.
我想创建一个我可以重用的泛型函数.我设法创建了一些(我认为)我需要的选项,但两者看起来都比我想象的要复杂得多.
为了清楚起见,这个函数的示例使用看起来像这样,serialDevice在一个单独的线程上吐出事件:
var eventOccurred = Helper.WaitForSingleEvent<StatusPacket>(
cancellationToken,
statusPacket => OnStatusPacketReceived(statusPacket),
a => serialDevice.StatusPacketReceived += a,
a => serialDevice.StatusPacketReceived -= a,
5000,
() => serialDevice.RequestStatusPacket());
Run Code Online (Sandbox Code Playgroud)
这个选项并不坏,但Dispose处理ManualResetEventSlim比看起来应该是更乱.它让ReSharper适合我在闭包内访问修改/处理的东西,而且真的很难遵循,所以我甚至不确定它是否正确.也许有一些我遗漏的东西可以清理它,这将是我的偏好,但我不会随便看到它.这是代码.
public static bool WaitForSingleEvent<TEvent>(this CancellationToken token, Action<TEvent> handler, Action<Action<TEvent>> subscribe, Action<Action<TEvent>> unsubscribe, int msTimeout, Action initializer = null)
{
var eventOccurred = false;
var eventResult = default(TEvent);
var o = new object();
var slim = new ManualResetEventSlim();
Action<TEvent> setResult = result …Run Code Online (Sandbox Code Playgroud) 如果我不得不猜测,我很确定答案是Clojure,但我不确定为什么.逻辑上(对我而言)看起来ClojureScript应该更快:
两者都是"动态的",但是ClojureScript
而Clojure:
那么Clojure如何比ClojureScript更快?当说JavaScript是动态的并且Clojure是动态的时,"动态"是否意味着不同的东西?我没看到什么?
(当然,如果ClojureScript 是确实快,然后是上面的推理是否正确?)
我想,Clojure编译成什么......至少是问题的一部分.我知道JVM部分不能只是一个普通的解释器(否则ClojureScript会更快),但是Clojure无法编译成常规字节码,因为JVM中没有"动态".那么ClojureScript的编译/执行方式与Clojure的编译/执行方式之间有什么区别?Java是如何编译/执行的,以及各自隐含的性能差异?
对下面的程序非常好奇(是的,在未附带调试器的情况下在发布模式下运行),第一个循环为数组的每个元素分配一个新对象,并且需要大约一秒钟才能运行.
所以我想知道哪个部分占用了最多的时间 - 对象创建或分配.所以我创建了第二个循环来测试创建对象所需的时间,第三个循环来测试分配时间,并且都在几毫秒内运行.这是怎么回事?
static class Program
{
const int Count = 10000000;
static void Main()
{
var objects = new object[Count];
var sw = new Stopwatch();
sw.Restart();
for (var i = 0; i < Count; i++)
{
objects[i] = new object();
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds); // ~800 ms
sw.Restart();
object o = null;
for (var i = 0; i < Count; i++)
{
o = new object();
}
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds); // ~ 40 ms
sw.Restart();
for (var i = 0; …Run Code Online (Sandbox Code Playgroud) PyPy GIL是RPython中PyPy解释器实现的一部分,还是translate.py自动添加的东西?也就是说,如果我要在RPython中编写我自己的新语言解释器并通过translate.py运行它,它是否会先于GIL,或者是由我的解释器代码决定的?
我很困惑为什么这个功能显示内存不断增加
let rec startRead1() =
async {
do! Async.Sleep 1
System.GC.Collect()
let mem = System.GC.GetTotalMemory(true)
printfn "%d" mem
do! startRead1()
}
Run Code Online (Sandbox Code Playgroud)
25676 36760 36840 36884 36928 36972 37016 37060 37104 37328 37362 37212 37456 37500 37544 37588 37632 37676 37720 37764 37808 37852 37896 37940 37984 38028 38072 38116 38160 38204 38248 38292 38336 38380 38424 38468 38512 38556 38600 38644 38688 38732 38776 38820 38864 38908 38952 38996 39040 39084 39128 39172 39216 ^ C按任意键继续...
[<EntryPoint>]
let main _ …Run Code Online (Sandbox Code Playgroud) 如果我已经定义了一系列记录(defrecord Person [name age])并且我想获得具有最大年龄的人的记录,那么有更简单的方法吗?
(reduce #(if (> (:age %1) (:age %2)) %1 %2) people)
Run Code Online (Sandbox Code Playgroud)
这是我到目前为止已经想到的唯一方法,但似乎这必须是一个常见的场景,必须有一些内置的库函数,使这更容易和/或更通用.
在F#中工作并实现"服务"模式,例如Web API或数据库或USB小工具的包装器时,这样做的惯用方法是什么?我的倾向是使用如IDatabase和Database,ITwitter和Twitter,ICamera和Camera接口和类只是想在C#中,允许简单的测试嘲笑.但我不想在F#中编写"C#",如果这不是标准的方法.
我考虑使用DU来表示例如Camera | TestCamera,但这意味着将所有模拟代码放入生产代码库中,这听起来很糟糕.但也许那只是我的OO背景说话.
我还考虑IDatabase过记录功能.我仍然对这个想法持开放态度,但似乎有点做作.此外,它排除了使用IoC控制器或任何"类MEF"插件功能的想法(至少我知道).
什么是"惯用F#"这样做的方式?只需遵循C#服务模式?