2015-09-17 13 views
9

リチャードバードのFask#を使用してファンクショナルアルゴリズムデザインのパールでHaskellアルゴリズムを書き直そうとしていますが、理解できないNullReferenceExceptionが発生しました。F#アルゴリズムで予期しないNullReferenceExceptionが発生しました

Haskellのアルゴリズム:

unmerges  :: [a] -> [([a], [a])] 
unmerges [x,y] = [([x], [y]), ([y], [x])] 
unmerges (x:xs) = [([x], xs), (xs, [x])] ++ 
        concatMap (add x) (unmerges xs) 
        where add x (ys, zs) = [(x:ys, zs), (ys, x:zs)] 

...期待通りに動作します:

*Main> unmerges [1,2] 
[([1],[2]),([2],[1])] 
*Main> unmerges [1,2,3] 
[([1],[2,3]),([2,3],[1]),([1,2],[3]),([2],[1,3]),([1,3],[2]),([3],[1,2])] 

私のF#バージョン:

let concatMap f m = List.map (fun x -> f x) m |> List.concat 

let rec unmerges (ints: 'a list) : ('a list * 'a list) list = 
    match ints with  
    | []  -> [] 
    | [x; y] -> [([x], [y]); ([y], [x])] 
    | x :: xs -> [([x], xs); (xs, [x])] @ 
       (let add x (ys, zs) = [(x::ys, zs); (ys, x::zs)] in 
        concatMap (add x) (unmerges xs)) 

...マッチングのために正常に動作します2つの要素リストを含むが、長いリストパターンと一致するときにエラーをスローする:

> unmerges [1;2];; 

val it : (int list * int list) list = [([1], [2]); ([2], [1])] 

> unmerges [1;2;3];; 

System.NullReferenceException: Object reference not set to an instance of an object 
    at Microsoft.FSharp.Core.Operators.op_Append[Tuple`2] (Microsoft.FSharp.Collections.FSharpList`1 list1, Microsoft.FSharp.Collections.FSharpList`1 list2) [0x00000] in <filename unknown>:0 
    at Microsoft.FSharp.Primitives.Basics.List.concat[Tuple`2] (IEnumerable`1 l) [0x00000] in <filename unknown>:0 
    at Microsoft.FSharp.Collections.ListModule.Concat[Tuple`2] (IEnumerable`1 lists) [0x00000] in <filename unknown>:0 
    at FSI_0055.concatMap[Tuple`2,Tuple`2] (Microsoft.FSharp.Core.FSharpFunc`2 f, Microsoft.FSharp.Collections.FSharpList`1 m) [0x00000] in <filename unknown>:0 
    at FSI_0055.unmerges[Int32] (Microsoft.FSharp.Collections.FSharpList`1 ints) [0x00000] in <filename unknown>:0 
    at <StartupCode$FSI_0057>[email protected]() [0x00000] in <filename unknown>:0 
    at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&) 
    at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0 
Stopped due to error 

addを個別に定義しようとしましたが、それは問題を強調しませんでした。私は、例外やデバッグの方法についての洞察に感謝します。

+0

また、これはMonoの問題である可能性があります。誰かがVisual F#で上記を実行する可能性がありますか? – THK

+0

F#の舐めを知らずに、私はあなたに健全性チェックを与えることができます。あなたのアルゴリズムは与えられたHaskellアルゴリズムと一致するようです。 – crockeea

+1

@THK:あなたのF#ポートはWindows上で問題なく動作します。 –

答えて

1

レコードは—ですが、確かにXamarinのバグでした(詳細は不明ですが、現在のアルファ版では5.10とMono 4.2.1で解決されています)。 - THK Sep 22 at 2:23

関連する問題