2

私はこの課題でいくつかの問題を抱えています。教授が求めているのは次のようなものです。

日付のリストを受け取り、オプションとして評価される 関数Oldest(int*int*int)を作成します。リストに日付がない場合は NONE と評価され、日付 d がリスト内で最も古い日付である場合は SOME d と評価されます。

関数の作成方法と日付のリストの操作方法については知っていますが、最も古い値を「保存」して日付のリストの末尾と比較する方法がわかりません。これは私が提出したものです(機能しません。常に最初の日付を取得しますが、答えを知りたいです)

fun oldest (datelist : (int * int * int) list) =
    if null datelist
    then NONE
    else if null (tl datelist) then
    SOME (hd datelist)
    else let val date = if is_older (hd datelist, hd (tl datelist)) then SOME (hd datelist) else SOME (hd (tl datelist))
     in oldest(tl datelist)
     end
4

1 に答える 1

5

再帰呼び出し間で値を保持する 1 つの方法は、引数で渡すことです。元の関数を変更することはできないため、最もよく使用される解決策は、この追加の引数を受け取るヘルパー関数を用意することです。
このようなヘルパー関数は、リストの末尾の再帰呼び出しで 2 つのうち最も古いものを使用して、リストの先頭を取得し、追加の引数と比較することができます。次に、リストが空の場合、この追加の引数を返すだけです。最も古いものでなければなりません。

fun oldestOfTwo (d1, d2) = (* return the oldest/minimum of the two dates *)

fun oldest [] = NONE
  | oldest (d::ds) =
    let
      fun oldest' max [] = SOME max
        | oldest' max (d::ds) =
          oldest (oldestOfTwo (max, d2)) ds
    in
      oldest' d ds
    end

もう 1 つの解決策は、リストの最初の 2 つの要素を取り出し、2 つのうち最も古いものを元に戻すことです。したがって、再帰呼び出しごとにリストの 1 つの要素を削除すると、ある時点でリストに 1 つの要素しかなくなります。一番古いはずです。

fun oldest [] = NONE
  | oldest [d] = SOME d
  | oldest (d1 :: d2 :: ds) = oldest (oldestOfTwo (d1, d2) :: ds)
于 2013-01-24T13:15:33.833 に答える