用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.