F# - Моно вылетает / возвращается непоследовательным

Я пытаюсь выучить F#, и у меня есть некоторый опыт в Standard 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 tree (* возвращает 6: int *)

Попытка первая - в F# Интерактивная оболочка F# 3.1 (эта разбивает оболочку)

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> genSize tree = 5

Попытка три - в MonoDevelop 5.9.4

Скопируйте код из Попытки 2 в MonoDevelop 5.9.4 и запустите его там, и он правильно вернет 6.

Вопрос:

Может ли кто-нибудь объяснить мне, что является причиной расхождения между попыткой 1 - 3?

Большое спасибо и всего наилучшего.

PS: Поскольку я в настоящее время изучаю F# и функциональное программирование, я стремлюсь реализовать большую часть функциональных возможностей библиотеки как часть процесса обучения.

След стека от Попытки 1

  • Утверждение в sgen-alloc.c:460, условие `*p == NULL'не выполнено

Трассировки стека:

в <0xffffffff> в (управляемый оболочкой) объект.__icall_wrapper_mono_object_new_specific (intptr) <0xffffffff> в FSI_0002.DEL.sigma (Microsoft.FSharp.Collections.FSharpList) 1<int>) <0x00013> at FSI_0002.DEL.genSize<a> (FSI_0002.DEL/genTree 1) <0x0005f> на FSI_0002.DEL/genSize@51.Invoke (FSI_0002.DEL / genTree 1<a>) <0x00023> at FSI_0002.DEL.map<FSI_0002.DEL/genTree 1, int> (Microsoft.FSharp.Core.FSharpFunc 2<FSI_0002.DEL/genTree 1, int>, Microsoft.FSharp.Collections.FSharpList 1<FSI_0002.DEL/genTree 1>) <0x00032> в 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 ) <0x00038> в Microsoft.FSharp.Collections.ListModule.Iterate (Microsoft.FSharp.Core.FSharpFunc`2, Microsoft.FSharp.Collections.FSharpList` 1 ) <0x00027> в Microsoft.FSharp.Compiler.Interactive.Shell.arg10@882 (Microsoft.FSharp.Compiler.Interactive.Shell/FsiDynamicCompiler,Microsoft.FSharp.Collections.FSharpList`1>>,Microsoft.FSharp.Core.Unit) <0x0005b> в Microsoft.FSharp.Compiler.Interactive.Shell/FsiDynamicCompiler.ProcessInputs (Microsoft.FSharp.Compiler.Interactive.Shell/FsiDynamicCompilerState,Microsoft.FSharp.Collections.FSharpList 1<Microsoft.FSharp.Compiler.Ast/ParsedInput>,bool,bool,bool,Microsoft.FSharp.Collections.FSharpList 1) <0x006e3> в Microsoft.FSharp.Compiler.Interactive.Shell/FsiDynamicCompiler.EvalParsedDefinitions (Microsoft.FSharp.Compiler.Interactive.Shell/FsiDynamicCompilerState,bool,bool,Microsoft.FSharp.holctions 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 22 >,a) <0x00039> в Microsoft.FSharp.Compiler.Interactive.Shell/FsiInteractionProcessor.ExecInteraction (bool,Microsoft.FSharp.Cigiler) Microsoft.FSharp.Compiler.Interactive.Shell/FsiDynamicCompilerState,Microsoft.FSharp.Compiler.Ast/ParsedFsiInteraction) <0x00067> в Microsoft.FSharp.Compiler.Interactive.Shell/FsiInteractionProcessor.omphl. TcConfig,Microsoft.FSharp.Compiler.Interactive.Shell/FsiDynamicCompilerState,Microsoft.FSharp.Core.FSharpOption1) <0x005fb> в Microsoft.FSharp.Compiler.Interactive.Shell/FsiInteractionProcessor. 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 2) <0x00039> в Microsoft.FSharp.Primitives.Basics.List.iter (Microsoft.FSharp.Core.FSharpFunc 2<T, Microsoft.FSharp.Core.Unit>,Microsoft.FSharp.Collections.FSharpList 1) <0x00038> в Microsoft.FSharp.Collections.ListModule.Iterate (Microsoft.FSharp.Core.FSharpFunc 2<T, Microsoft.FSharp.Core.Unit>,Microsoft.FSharp.Collections.FSharpList 1) <0x00027> at. $ Fsiaux.run @ 35 (Microsoft.FSharp.Compiler.Interactive.SimpleEventLoop, Microsoft.FSharp.Core.Unit) <0x000d3> в Microsoft.FSharp.Compiler.Interactive.SimpleEventLoop.Microsoft-FSharp-Compiler-Interactive-IEventLoop-Run () <0x0001f> в Microsoft.FSharp.Compiler.Interactive.Shell.runLoop@2066 (Microsoft.FSharp.Compiler.Interactive.Shell/FsiConsoleOutput,Microsoft.FSharp.Core.Unit) <0x00205> по адресу Microsoft.FSharp.Compiler.Interactive.Shell.DriveFsiEventLoop (Microsoft.FSharp.Compiler.Interactive.Shell/FsiConsoleOutput) <0x0001b> по адресу Microsoft.FSharp.Compiler.Interactive.Shell/FsiEvaluationSession.Run ().FSharp.Compiler.Interactive.Shell.evaluateSession@2382 (string[],Microsoft.FSharp.Core.Unit) <0x0009b> в Microsoft.FSharp.Compiler.Interactive.Shell.MainMain (string[]) <0x00123> в Microsoft.FSharp.Compiler.Interactive.Main.FsiMain (string[]) <0x00013> at (вызов времени выполнения оболочки) .runtime_invoke_int_object (object,intptr,intptr,intptr) <0xffffffff>

Родная трассировка стека:

mono() [0x8102a23]
[0xb775240c]
[0xb7752424]
/lib/i386-linux-gnu/libc.so.6(gsignal+0x47) [0xb7545607]
/lib/i386-linux-gnu/libc.so.6(abort+0x143) [0xb7548a33]
mono() [0x827b381]
mono() [0x827b508]
mono() [0x827b5a3]
mono() [0x8233338]
mono() [0x8233a4c]
mono() [0x81f20a8]
mono(mono_object_new_alloc_specific+0x40) [0x81f6570]
mono(mono_object_new_specific+0x88) [0x81f6628]
[0xb725cc71]
[0xb25a974c]
[0xb25a9640]
[0xb25a9724]
[0xb25a96c3]
[0xb25a9637]
[0xb25a94ac]
[0xb725b5f7]
mono() [0x80723d1]

Отладочная информация из GDB:

Не удалось подключиться к процессу. Если ваш uid совпадает с uid целевого процесса, проверьте настройку /proc/sys/kernel/yama/ptrace_scope или попробуйте снова как пользователь root. Для получения дополнительной информации см. /Etc/sysctl.d/10-ptrace.conf ptrace: операция не разрешена. Нет тем.

================================================== =============== Получил SIGABRT при выполнении нативного кода. Это обычно указывает на фатальную ошибку в моно среде выполнения или в одной из собственных библиотек

используется вашим приложением.

Отменено

1 ответ

Решение

Похоже, моно ошибка. Я тестировал как VS2013, так и VS2015, и ваш код работает просто отлично. Если вы можете получить трассировку стека, я бы отправил сообщение об ошибке парням из Mono.

Я получаю ту же трассировку стека, что и вы. Для записи по версии Mono

Моно JIT-компилятор версии 4.0.2 ((отсоединен /c99aa0c чт 11 июня 18:53:01 ПО ВОСТОЧНОМУ ВРЕМЕНИ 2015)

Если вы Google "Утверждение на sgen-alloc.c:460, условие`*p == NULL'не выполнено ", вы увидите несколько ссылок на эту ошибку с Mono.

РЕДАКТИРОВАТЬ: Протестировано на Mono 4.0.3, и он имеет ту же проблему. Что интересно, если вы сделаете genTree не общим

type genTree = GenNode of string * genTree list

это работает отлично.

Другие вопросы по тегам