python - OCaml 相当于 Python 生成器

标签 python ocaml generator

法国 Sécurité Sociale 身份证号码以两位数的校验码结尾。我已验证可以检测到所有可能的 common transcription error,并发现了一些可能未检测到的其他类型的错误(例如,滚动三个连续数字)。

def check_code(number):
    return 97 - int(number) % 97

def single_digit_generator(number):
    for i in range(len(number)):
        for wrong_digit in "0123456789":
            yield number[:i] + wrong_digit + number[i+1:]

def roll_generator(number):
    for i in range(len(number) - 2):
        yield number[:i] + number[i+2] + number[i] + number[i+1] + number[i+3:]
        yield number[:i] + number[i+1] + number[i+2] + number[i] + number[i+3:]

def find_error(generator, number):
    control = check_code(number)
    for wrong_number in generator(number):
        if number != wrong_number and check_code(wrong_number) == control:
            return (number, wrong_number)

assert find_error(single_digit_generator, "0149517490979") is None
assert find_error(roll_generator, "0149517490979") == ('0149517490979', '0149517499709')

我的 Python 2.7 代码(上面的工作片段)大量使用了生成器。我想知道如何在 OCaml 中调整它们。我当然可以编写一个函数来维护一些内部状态,但我正在寻找一个纯函数解决方案。我可以研究我不太熟悉的库 lazy 吗?我不是要代码,只是要方向。

最佳答案

您可以简单地将生成器定义为,使用语言的扩展:

let range n = Stream.from (fun i -> if i < n then Some i else None);;

for 语法结构不能与之一起使用,但是 Stream 模块提供了一组函数来检查流的状态并迭代其元素.

try
  let r = range 10 in
  while true do
    Printf.printf "next element: %d\n" @@ Stream.next r
  done
with Stream.Failure -> ();;

或者更简单地说:

Stream.iter (Printf.printf "next element: %d\n") @@ range 10;;

您还可以使用 camlp4 预处理器提供的特殊语法:

Stream.iter (Printf.printf "next element: %d\n") [< '11; '3; '19; '52; '42 >];;

其他功能包括从列表、字符串、字节甚至 channel 中创建流。 API documentation 简明扼要地描述了不同的可能性。

特殊的语法让你可以组合它们,以便在之前或之后放回元素,但一开始它可能有点不直观:

let dump = Stream.iter (Printf.printf "next element: %d\n");;

dump [< range 10; range 20 >];;

将生成第一个流的元素,然后在第二个流的元素排名 紧接 最后一个生成的元素的排名之后,因此在这种情况下它看起来就像只有第二个流得到迭代。

要获取所有元素,您可以构造一个 'a Stream.t 流,然后对每个元素进行递归迭代:

Stream.iter dump [< '(range 10); '(range 20) >];;

这些将产生预期的输出。

我建议阅读有关 OCaml 的旧书(可用 online )以获得对该主题的更好介绍。

关于python - OCaml 相当于 Python 生成器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28353442/

相关文章:

c - 在 C 中无法理解此 PRNG 代码

python - tkinter tkMessageBox html 链接

python - 用python划分两个数据框

python - 如果已经存在,则返回类实例而不是创建新实例

python - 正则表达式用于解析带引号的子字符串的查询并返回单个单词的嵌套列表

types - 在定义它们的模块之外使用开放联合

OCaml `Map.Make` 输入模块

arrays - OCaml 中的数组操作

matrix - 从 ldpc 奇偶校验矩阵生成生成器矩阵

image-processing - Keras ImageDataGenerator 如何查看修改图像的参数