2011-12-18 22 views
3

SMLで非常に簡単な関数を書く必要があります。値 'elem'がリスト 'L'のフィールド 'f1'のいずれの値よりも大きいかどうかをチェックする必要があります。リスト 'L'には、 'f1'、 'f2'、 'f3'の3つのフィールドがあります。関数 'elem> f1'がリスト 'L'のメンバーのいずれかに対して真である場合、関数は1を返すべきです。それ以外の場合、この関数は例えば0を返す必要があります:リストのWHILEループ

L = 
f1 f2 f3 
1 4 6 
2 1 2 
3 4 8 
8 5 9 

elem = 3 

fun check(L: myList, elem: int): int = 
let 
    val counter = ref 0 
    val counter_end = length L 
in 
     while (!counter <= counter_end) do 
      let val f1 = List.nth(L,counter) 
      in 
       if elem > f1 then 1 else 0 
      end 
      counter := !counter + 1 
end 

私はリスト「L」からフィールド「F1」を取得する方法がわかりません。どんなアイデアも高く評価されています。

+2

whileループを使用している特定の理由はありますか?それは一般的にSMLのひどい考えです。 – jalf

+0

まあ、私はSMLの初心者なので、私の問題を解決する方法は他にありません。しかし、あなたが他の解決策を知っているなら、ここでそれを説明してください。どうも。 –

+0

関数は何を返すべきですか?リストのメンバーが 'elem> f1'を持たない場合にはどうなるでしょうか? – jalf

答えて

2

を、あなたは通常、再帰ではなく、ループのような必要不可欠構造に依存することをお勧めします。

私はSMLに少しさびたんだけど、ここではそれは、このように呼び出すことができます

fun check elem [] = 0 
    | check elem ((f1,f2,f3)::tl) = if elem > f1 then 1 else check elem tl; 

関数を定義する一つの方法です:

(* define a list to scan *) 
val L = [(1,4,6),(2,1,2),(3,4,8),(8,5,9)]; 
(* call the function on our list *) 
check 3 L; 

機能を使用して、再帰的に定義されているが、パターンマッチング:最初の行は、関数が空のリストで呼び出された場合、結果はゼロであることを示します。 2番目の行は、最初の要素がタプル(f1,f2,f3)であるリスト上で呼び出された場合、elem > f1の場合は1になり、それ以外の場合は、リストの末尾で再帰的に関数を呼び出す結果になります。

また、型指定子は省略しました。言語は自動的に型を推定するため、ほとんど必要としません。コンパイラは、あなたが書いたコードでどんな型を安全に使うことができるのかをすでに知っています。だから、引数がどんな型になると思いますか?

+0

ありがとうございます。 –

2

ループを使用する代わりに再帰関数を使用します。 (そして、おそらく整数の代わりにブール型の戻り値を使う方がいいでしょう)

フィールドを抽出する最も簡単な方法は、引数リストのパターンマッチングです。 、あなたの三つのフィールドをタプルである。このようなものと仮定:SML(と一般的には関数型言語)で

fun check((f1,f2,f3)::L: myList, elem: int)