2012-03-09 12 views
4

私は現時点でsmlnjを勉強しようとしており、折り畳み機能に問題があります。SMLの折り畳みを使用

私がしようとしているのは、折りたたみパターンを使用して関数とリストを取り込む関数selectを書くことです。リストの先頭を関数に渡して、その要素をリストに追加するかどうかを決定します。ここに私が意味するものの例があります。

  select (fn x => x mod 2 = 0) [1,2,3,4,5,6,7,8,9,10]; 
      val it = [2,4,6,8,10] : int list 

だから、ここ

  fun select f l = foldl (fn (x,y) => if (f(x)) then x else 0) 0 l; 

これは明らかに正しく動作しません...私はこれまで持っているものです。これは単純に10を返します。私はop ::を何とか使う必要があると確信していますが、これを理解することはできません。私の考えは、このように見えるはずです...

  fun select f l = foldl (fn (x,y) => if (f(x)) then op:: else []) [] l; 

これは機能しません。どんな助けもありがとう。ありがとう!

答えて

4

あなたが近くにいるために最も適しているであろうかどうか考えてみてください。唯一の問題は、foldに渡す関数のif/elseケースです。

fn (x,y)xは、あなたが検討しているリスト要素であり、yは残りのリストを折り畳んだ結果であることを覚えておいてください。 f(x)が失敗した場合は、結果からxを除外したいので、yを渡すだけです。 f(x)が成功した場合は、xを結果に含めるので、[email protected][x]を返します。

補間演算子([email protected][x])は、線形時間演算であるため、プリペイド(x::y)は定数ですが、使用することを避けることをお勧めします。もちろん、この場合にはもう一方を代入することで、あなたのリストを後方に構築します。これを回避するには、foldlの代わりにfoldrを使用します。

+0

ありがとう!これは完全に私のためにそれをクリアします。 – MCR

2

実装しているものは既に存在します。それはfilterと呼ばれています。

- List.filter (fn x => x mod 2 = 0) [1,2,3,4,5,6,7,8,9,10]; 
val it = [2,4,6,8,10] : int list 

2番目のコードサンプルでの試行はかなり近似しています。私が指摘するいくつかの問題があります:

  • op::は演算子です。おそらく、関数を返すことは望ましくありません。代わりに、演算子を使用してhead要素とリストの残りの部分から次のようなリストを作成したいと思うでしょう:x :: y

  • 現在、空リストを返していますyに蓄積されました。あなたはおそらくそれをしたくありません。

  • は左倍または右倍はあなたの出力

+0

ありがとうございます。私は本当にあなたの助言に感謝します。 – MCR

関連する問題