用Autolisp实现Racket SRFI 1的一些函数(续)
SRFI 1 是 scheme 的标准的一种补充,包括 Racket 在内的 scheme 实现(变种、方言),通常都会支持大部分的 SRFI。
SRFI 1 是关于 list 的,它提供几十个常用的 list 函数,对 R4RS/R5RS两版 scheme 标准来说非常有用,
因为这两版标准删除了很多常用的 list 函数。
SRFI 1 的函数,之前用 autolisp 写过一些,现在接着写。
split-at 函数
split-at函数接受 2 个参数,1 个 list 和 1 个整数 n,它把 list 分为 2 个 list,1 个是元素索引大于等于 n 的,
剩下的元素组成另一个 list。
比如,(split-at '(a b c d e f g h) 3) => ((a b c)(d e f g h)),它在 scheme 中的实现是返回 2 个值,
autolisp 不支持返回多值,所以就写成 2 个子 list。
上面这个写法,用到了之前实现的 take 和 drop 函数,有兴趣的朋友可以看看之前的 blog。
span 函数
span 函数也是用作分割list的,它接受2参数,1个函数符合f,1个list。它按从左到右的顺序,查找 (f x) 为真值的 list 元素,
直到 (f x) 不是真值为止,按照这个标准将list分割为2个list。
比如,(span 'even? '(2 18 3 10 22 9)) => ((2 18)(3 10 22 9))。
break 函数
break 函数与 span 函数很相似,不同点在于,break 是找不符合条件的,直到碰到符合条件的为止。
比如,(break 'even? '(3 1 4 1 5 9)) => ((3 1)(4 1 5 9))。
fold 函数
fold 函数相当于其他编程语言里边的reduce函数,功能大同小异,主要是名称不同而已。 fold 接受 3 个参数,1个函数符号f,
1个值a,1个list,它从左到右依次用list的每个元素x来求取 (f x a) 的值,把每次取得的值赋给a,然后,
用新的a和list的下一个元素一起传给f求值,直到到达list末尾,返回最后1次的 (f x a)的值。
与其他的函数式编程语言里边的类似函数相比,SRFI 1 的 fold 函数具有不同的行为,它按照 (f x a) 方式求值,
clojure 和 haskell 是 按照 (f a x) 的方式求值。
我在这里给出符合 clojure 和 haskell 的autolisp实现。
fold-right
fold-right 与 fold 函数的区别在于,它是从右往左依次拿list的元素去求值的。
后记
SRFI 1的函数有几十个,到目前为止这几篇blog只给出了十来个函数的 autolisp 实现,其余的之所以没有做出来,
是因为那些主要是各种判断函数,再就是一些具有副作用的函数变种。
文章作者 Jack Hsu
上次更新 2023-11-19
许可协议 Copyright © Jack Hsu. All Rights Reserved.