2

私は SML に非常に慣れていないので、リストの演習を試みています。目標は、リストの以前の数を合計して、新しいリストを作成することです。たとえば、入力リスト[1, 4, 6, 9]は を返し[1, 5, 11, 20]ます。

これはこれまでの私の解決策ですが、問題は関数の定義方法にあると思います。

fun rec sum:int list -> int list = 
    if tl(list) = nil then 
      hd(list)
    else 
      hd :: sum((hd(tail) + hd(tl(list)))::tl(tl(list)));
4

2 に答える 2

3

rec を関数名として使用していることに加えて、取り組むべき小さな問題がいくつかあります。

  • 作成した明示的な型注釈は、関数結果の注釈として扱われます。したがって、あなたが書いたことによると、期待されるリストではなく、関数を返す必要があります。これは、次の例から明らかです。

    - fun rec_ sum : int list -> int list = raise Domain;
    val rec_ = fn : 'a -> int list -> int list
    
  • リスト内の要素の数をチェックしない場合は、head 関数と tail 関数の使用に注意する必要があります。これは、長さ関数を使用するか、または (さらに簡単で、多くの場合より優れた) 要素数のパターン マッチングを使用して行うことができます。

  • コードには、関数呼び出しとしての sum と変数としての tail が含まれています。変数 tail は一度も定義されておらず、関数呼び出しとして sum を使用すると、実際に rec をキーワードとして使用していると思われますが、それが何を意味するのかわかりません。

    val キーワードを使用して関数を定義する場合、キーワード rec が使用されます。この場合、再帰関数を定義できるようにするために rec が必要です (大きな驚きではありません)。実際には、キーワード fun は val rec の構文糖衣 (派生形) です。

以下の 3 つは、その作成方法の例です。

1 つ目は、シンプルでわかりやすいソリューションです。

fun sumList1 (x::y::xs) = x :: sumList1 (x+y::xs)
  | sumList1 xs = xs

この 2 番目の例では、引数 (アキュムレータ) を追加したヘルパー関数を使用しています。遅い追加 (@) 演算子の使用を避けるために、リストは逆の順序で作成されます。したがって、リストを返す前に逆にします。

fun sumList2 xs =
    let
      fun sumList' [] acc  = rev acc
        | sumList' [x] acc = rev (x::acc)
        | sumList' (x :: y :: xs) acc = sumList' (y+x :: xs) (x :: acc)
    in
      sumList' xs []
    end

最後の例は、標準のリスト関数を使用すると、いかに小さく簡単にできるかを示しています。ここでは、すべての要素を通過するために左折が使用されます。繰り返しますが、リストは逆の順序で作成されていることに注意してください。つまり、最後のステップで逆になっています。

fun sumList3 []      = []
  | sumList3 (x::xs) = rev (foldl (fn (a, b) => hd b + a :: b) [x] xs)
于 2013-01-14T01:55:51.027 に答える
2

これを試して -

fun recList ([], index, sum) = []
  | recList (li, index, sum) =
    if index=0 then
        hd li :: recList (tl li, index+1, hd li)
    else
      sum + hd li :: recList (tl li, index+1, sum + hd li)

fun recSum li = recList (li, 0, 0)

あなたの場合 -

recSum([1,4,6,9]) ;

あげる

val it = [1,5,11,20] : int list 

recまた、楽しい名前 -it キーワードとして使用しないでください。

于 2013-01-13T21:13:43.670 に答える