F# - 单声道崩溃/返回不一致

时间:2015-07-27 08:57:27

标签: f# mono sml f#-interactive

我正在尝试学习F#,我在标准ML中有一些背景知识。我正在编写文本"功能方法编程"将其代码转换为F#。下面提供的代码示例来自上面提到的那本书。

在SML中

datatype 'a genTree = GenNode of 'a * ('a genTree list);;

val tree: string genTree =
  GenNode("a", [GenNode("b", []),
                GenNode("c", [GenNode("d", []),
                              GenNode("e", [])]),
                GenNode("f", [])]);;

fun map f [] = []
  | map f (l::ls) = (f l) :: (map f ls);;

fun foldl f e [] = e
  | foldl f e (l::ls) = foldl f (f(e, l)) ls;;

fun sigma xs = foldl (op +) 0 xs;;

fun genSize (GenNode(_, ls)) =
    1 + sigma (map genSize ls);;

SML> genSize树(*返回6:int *)

尝试一个 - 在F#Interactive Shell F#3.1中(这个崩溃了shell)

type genTree<'a> = GenNode of 'a * genTree<'a> list;;

let tree: string genTree =
  GenNode("a", [GenNode("b", []);
                GenNode("c", [GenNode("d", []);
                              GenNode("e", [])]);
                GenNode("f", [])]);;

let rec map f ls =
  match ls with
  | [] -> []
  | (l::ls) -> (f l) :: (map f ls);;

let rec foldl f e ls =
  match ls with
  | [] -> e
  | (l::ls) -> foldl f (f e l) ls;;

let sigma ls = foldl ( + ) 0 ls;;

let rec genSize (GenNode(lbl, ls)) =
  1 + sigma(map genSize ls);;

尝试两个 - 在F#Interactive Shell F#3.1中(为genSize提供一个基本案例,希望能够做到这一点!)

这是genSize的新定义,来自尝试#1的其余代码保持不变。

let rec genSize (t: genTree<'a>) =
  match t with
  | GenNode(_, []) -> 1
  | GenNode(_, ls) -> 1 + sigma (map genSize ls);;

FSI&GT; genSize tree = 5

尝试三 - 在MonoDevelop 5.9.4

将代码从Attempt 2复制到MonoDevelop 5.9.4并在那里运行并正确返回6.

问题:

有人可以向我解释是什么导致了1 - 3之间的差异吗?

非常感谢和亲切的问候。

PS:由于我目前正在学习F#和函数式编程,因此我倾向于将大部分库函数作为学习过程的一部分来实现。

来自尝试1的堆栈轨道

  • sgen-alloc.c:460中的断言,条件`* p == NULL&#39;没见过

堆栈跟踪:

at&lt; 0xffffffff&gt;   at(包装器托管到原生)对象.__ icall_wrapper_mono_object_new_specific(intptr)&lt; 0xffffffff&gt;   在FSI_0002.DEL.sigma(Microsoft.FSharp.Collections.FSharpList 1<int>) <0x00013> at FSI_0002.DEL.genSize<a> (FSI_0002.DEL/genTree 1)&lt; 0x0005f&gt;   在FSI_0002.DEL/genSize@51.Invoke(FSI_0002.DEL / genTree 1<a>) <0x00023> at FSI_0002.DEL.map<FSI_0002.DEL/genTree 1,int&gt;(Microsoft.FSharp.Core.FSharpFunc 2<FSI_0002.DEL/genTree 1,int&gt ;,Microsoft.FSharp.Collections.FSharpList 1<FSI_0002.DEL/genTree 1&gt;)&lt; 0x00032&gt;   在FSI_0002.DEL.genSize(FSI_0002.DEL / genTree 1<a>) <0x00056> at <StartupCode$FSI_0004>.$FSI_0004.main@ () <0x0001b> at (wrapper runtime-invoke) object.runtime_invoke_void (object,intptr,intptr,intptr) <0xffffffff> at <unknown> <0xffffffff> at (wrapper managed-to-native) System.Reflection.MonoMethod.InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&) <0xffffffff> at System.Reflection.MonoMethod.Invoke (object,System.Reflection.BindingFlags,System.Reflection.Binder,object[],System.Globalization.CultureInfo) <0x000c0> at System.MonoType.InvokeMember (string,System.Reflection.BindingFlags,System.Reflection.Binder,object,object[],System.Reflection.ParameterModifier[],System.Globalization.CultureInfo,string[]) <0x0039a> at System.Reflection.Emit.TypeBuilder.InvokeMember (string,System.Reflection.BindingFlags,System.Reflection.Binder,object,object[],System.Reflection.ParameterModifier[],System.Globalization.CultureInfo,string[]) <0x00066> at System.Type.InvokeMember (string,System.Reflection.BindingFlags,System.Reflection.Binder,object,object[],System.Globalization.CultureInfo) <0x0005a> at Microsoft.FSharp.Compiler.AbstractIL.ILRuntimeWriter/execEntryPtFun@1986-1.Invoke (Microsoft.FSharp.Core.Unit) <0x00083> at Microsoft.FSharp.Compiler.Interactive.Shell/clo@883-37.Invoke (Microsoft.FSharp.Core.FSharpFunc 2,Microsoft.FSharp.Collections.FSharpList`1&lt; T&gt;)&lt; 0x00038&gt;   在Microsoft.FSharp.Collections.ListModule.Iterate&lt; T&gt; (Microsoft.FSharp.Core.FSharpFunc`2,Microsoft.FSharp.Collections.FSharpList`1&lt; T&gt;)&lt; 0x00027&gt;   在Microsoft.FSharp.Compiler.Interactive.Shell.arg10@882(Microsoft.FSharp.Compiler.Interactive.Shell/FsiDynamicCompiler,Microsoft.FSharp.Collections.FSharpList`1>>,Microsoft.FSharp.Core.Unit)&lt; 0x0005b&GT;   在Microsoft.FSharp.Compiler.Interactive.Shell/FsiDynamicCompiler.ProcessInputs(Microsoft.FSharp.Compiler.Interactive.Shell/FsiDynamicCompilerState,Microsoft.FSharp.Collections.FSharpList{ {1}} 1)&lt; 0x006e3&gt;   在Microsoft.FSharp.Compiler.Interactive.Shell/FsiDynamicCompiler.EvalParsedDefinitions(Microsoft.FSharp.Compiler.Interactive.Shell/FsiDynamicCompilerState,bool,bool,Microsoft.FSharp.Collections.FSharpList1<Microsoft.FSharp.Compiler.Ast/ParsedInput>,bool,bool,bool,Microsoft.FSharp.Collections.FSharpList22<a,Microsoft.FSharp .Compiler.Interactive.Shell / FsiInteractionStepStatus&gt;&gt;,a)&lt; 0x00039&gt;   在Microsoft.FSharp.Compiler.Interactive.Shell/FsiInteractionProcessor.ExecInteraction(bool,Microsoft.FSharp.Compiler.Build / TcConfig,Microsoft.FSharp.Compiler.Interactive.Shell / FsiDynamicCompilerState,Microsoft.FSharp.Compiler.Ast / ParsedFsiInteraction)&lt ; 0x00067&GT;   在Microsoft.FSharp.Compiler.Interactive.Shell/FsiInteractionProcessor.ExecInteractions(bool,Microsoft.FSharp.Compiler.Build / TcConfig,Microsoft.FSharp.Compiler.Interactive.Shell / FsiDynamicCompilerState,Microsoft.FSharp.Core.FSharpOption1)&lt; 0x005fb&gt; ;   在Microsoft.FSharp.Compiler.Interactive.Shell/FsiInteractionProcessor.MainThreadProcessParsedInteraction(bool,Microsoft.FSharp.Core.FSharpOption 1<Microsoft.FSharp.Compiler.Ast/SynModuleDecl>) <0x001db> at Microsoft.FSharp.Compiler.Interactive.Shell/FsiDynamicCompiler.EvalParsedExpression (Microsoft.FSharp.Compiler.Interactive.Shell/FsiDynamicCompilerState,Microsoft.FSharp.Compiler.Ast/SynExpr) <0x0005f> at Microsoft.FSharp.Compiler.Interactive.Shell/clo@1590-45.Invoke (Microsoft.FSharp.Compiler.Interactive.Shell/FsiDynamicCompilerState) <0x012ef> at Microsoft.FSharp.Compiler.Interactive.Shell/FsiInteractionProcessor.InteractiveCatch<a> (Microsoft.FSharp.Core.FSharpFunc 2)&lt; 0x00039&gt;   在Microsoft.FSharp.Primitives.Basics.List.iter(Microsoft.FSharp.Core.FSharpFunc 1<Microsoft.FSharp.Compiler.Ast/ParsedFsiInteraction>,Microsoft.FSharp.Compiler.Interactive.Shell/FsiDynamicCompilerState) <0x0013b> at Microsoft.FSharp.Compiler.Interactive.Shell/res@1782.Invoke (Microsoft.FSharp.Compiler.Interactive.Shell/FsiDynamicCompilerState) <0x00033> at Microsoft.FSharp.Compiler.Interactive.Shell/runCodeOnMainThread@2021-2.Invoke (Microsoft.FSharp.Core.Unit) <0x0003b> at <StartupCode$FSharp-Compiler-Interactive-Settings>.$Fsiaux/Microsoft-FSharp-Compiler-Interactive-IEventLoop-Invoke@47.Invoke (Microsoft.FSharp.Core.Unit) <0x0001a> at <StartupCode$FSharp-Compiler-Interactive-Settings>.$Fsiaux/run@38-4.Invoke (Microsoft.FSharp.Core.FSharpFunc 1)&lt; 0x00038&gt;   在Microsoft.FSharp.Collections.ListModule.Iterate(Microsoft.FSharp.Core.FSharpFunc 2<T, Microsoft.FSharp.Core.Unit>,Microsoft.FSharp.Collections.FSharpList 1)&lt; 0x00027&gt;   at。$ Fsiaux.run @ 35(Microsoft.FSharp.Compiler.Interactive.SimpleEventLoop,Microsoft.FSharp.Core.Unit)&lt; 0x000d3&gt;   在Microsoft.FSharp.Compiler.Interactive.SimpleEventLoop.Microsoft-FSharp-Compiler-Interactive-IEventLoop-Run()&lt; 0x0001f&gt;   在Microsoft.FSharp.Compiler.Interactive.Shell.runLoop@2066(Microsoft.FSharp.Compiler.Interactive.Shell/FsiConsoleOutput,Microsoft.FSharp.Core.Unit)&lt; 0x00205&gt;   在Microsoft.FSharp.Compiler.Interactive.Shell.DriveFsiEventLoop(Microsoft.FSharp.Compiler.Interactive.Shell/FsiConsoleOutput)&lt; 0x0001b&gt;   在Microsoft.FSharp.Compiler.Interactive.Shell/FsiEvaluationSession.Run()&lt; 0x00bfb&gt;   在Microsoft.FSharp.Compiler.Interactive.Shell.evaluateSession@2382(string [],Microsoft.FSharp.Core.Unit)&lt; 0x0009b&gt;   在Microsoft.FSharp.Compiler.Interactive.Shell.MainMain(string [])&lt; 0x00123&gt;   在Microsoft.FSharp.Compiler.Interactive.Main.FsiMain(string [])&lt; 0x00013&gt;   at(wrapper runtime-invoke).runtime_invoke_int_object(object,intptr,intptr,intptr)&lt; 0xffffffff&gt;

原生堆栈跟踪:

2<T, Microsoft.FSharp.Core.Unit>,Microsoft.FSharp.Collections.FSharpList

来自gdb的调试信息:

无法附加到进程。如果你的uid与目标的uid匹配 进程,检查/ proc / sys / kernel / yama / ptrace_scope的设置,或者尝试 再次作为root用户。有关更多详细信息,请参阅/etc/sysctl.d/10-ptrace.conf ptrace:不允许操作。 没有线程。

=============================================== ================== 执行本机代码时获得SIGABRT。这通常表明 单声道运行时或其中一个本机库中的致命错误

由您的应用程序使用。

中止

1 个答案:

答案 0 :(得分:0)

看起来像一个Mono bug。我在VS2013和VS2015都进行了测试,你的代码运行得很好。如果你能抓住堆栈跟踪,我会向Mono家伙提出一个错误。

我得到的堆栈跟踪与你相同。 Mono版本的记录是

  

Mono JIT编译器版本4.0.2((分离/ c99aa0c Thu Jun 11 18:53:01 EDT 2015)

如果你谷歌“断言sgen-alloc.c:460,条件`* p == NULL'不符合”,你会看到Mono对这个错误的一些引用。

编辑:在Mono 4.0.3上测试过它有同样的问题。有趣的是,如果你使genTree非通用,如

type genTree = GenNode of string * genTree list

效果很好。