0

我正在尝试“双重”过滤两个列表,具体取决于痛苦地通过数据类型测试而不使用 HOP 进行递归。以下是我非常丑陋的解决方案尝试......

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. 提取通过的测试的名称。

好的,那么我们如何确定列表中的所有值是否都通过了一项测试?很简单,我们使用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'a test list而不是 a 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 回答