0

HOPを使用した再帰なしで、データ型テストに合格することに応じて、2つのリストを「二重」にフィルタリングしようとしています。以下は、解決策に対する私の非常に醜い試みです...

datatype 'a test = Test of ('a -> bool) * string;

fun foo xs lst = 
    let 
        fun foo_bar(x, ls) =
            let                
                val tests = (List.filter (fn (Test(f, str)) => (f x)) ls)
            in
                (List.map (fn (Test(f, str)) => str) tests)
            end 
    in
        (List.map (fn x => foo_bar(x, lst)) xs)
    end;

allPass: 'a list -> 'a test list -> 'a test list;

allPass [1, 2, 40, 150] [positive, even]文字列を返す必要があります"pos"

現在、私の関数はネストされたリストを返しています: [["pos"], ["pos even"], ["pos even"], ["pos even"]]. この結果から「pos」だけを抽出する非再帰的な方法はありますか、それともこの問題を完全に間違った方向に解決しようとしていますか?

4

1 に答える 1

0

あなたは正しい方向に向かっていますが、まだそこにはいません。これがあなたが欲しいと思うものです。

値のリストとテストのリストを取得します。すべての値が合格するテストの名前のリストを返します。

では、次のことを行う必要があります。

  1. テストのリストをフィルタリングします。テストの述語は、すべての値が合格する必要があるということです。
  2. 合格したテストの名前を抽出します。

では、リスト内のすべての値が 1 つのテストに合格するかどうかをどのように判断すればよいのでしょうか? シンプルに、 を使用しますList.all

List.all    : ('a -> bool) -> 'a list -> bool

関数を定義できます。

fun allPassesTest xs (Test(f,s)) = List.all f xs

trueこれは、xs のすべての値がテストに合格した場合にのみ返されます。次に、この関数に基づいて、テストのリストをフィルタリングします。

fun allPass xs tests = List.filter allPassesTest xs tests

'a test listただし、これはではなく を返すstring listため、名前を抽出する必要があります。

fun name (Test(f,s)) = s
fun allPass xs tests = map name (List.filter allPassesTest xs tests)
于 2013-02-11T19:13:47.150 に答える