定义布尔简单数组类型



我正在尝试为布尔简单数组定义一种类型。这应该很容易:

(deftype boolean-vector (&optional (length '*))
"Simple vector of BOOLEAN elements."
`(simple-array boolean (,length)))

然而:

CL-USER> (typep #(nil nil t t t) 'boolean-vector)
T
CL-USER> (typep #(nil nil t t 5) 'boolean-vector)
T
CL-USER> (typep 5 'boolean)
NIL

有人知道为什么这个deftype没有做它应该做的事情,以及如何正确定义只包含boolean类型元素的向量类型吗?

答案下面有两个很好的解释。我最终做了什么:

(defun boolean? (object)
"Check type of OBJECT is BOOLEAN."
(typep object 'boolean))
(defun boolean-sequence-p (x)
(every #'boolean? x))
(deftype simple-boolean-vector (&optional (length '*))
"Vector of BOOLEAN elements."
`(and (simple-array * (,length))
(satisfies boolean-sequence-p)))

deftype正在做它应该做的事情,但

> (upgraded-array-element-type 'boolean)
t

换句话说,没有一种专门的数组类型只能容纳tnil:在您的实现中,不可能有一个数组只能容纳booleans。当然,实施有可能支持这样的事情,但我认为这是极不可能的。

如果您想要一个只能包含true或false值的数组类型,那么您可能想要bit-vectors,它需要存在,并带有一些包装。例如:

(deftype array-index ()
`(integer 0 (,array-dimension-limit)))
(defun make-boolean-vector (n &key (initial-element nil))
(declare (type array-index n)
(type boolean initial-element))
(make-array (list n) :element-type  'bit :initial-element (if initial-element 1 0)))
(declaim (inline bref (setf bref)))

(defun bref (v n)
(declare (type bit-vector v)
(type array-index n))
(= (bit v n) 1 t nil))
(defun (setf bref) (b v n)
(declare (type bit-vector v)
(type array-index n)
(type boolean b))
(setf (bit v n) (if b 1 0))
b)

试试这个:

(defun bool-array (a)
(and (simple-array-p a)
(every (lambda (e) (typep e 'boolean)) a)))
(deftype boolean-vector ()
`(satisfies bool-array))

测试:

> (typep #(nil nil t t t) 'boolean-vector)
T
> (typep #(nil nil t t 5) 'boolean-vector)
NIL
> (typep 5 'boolean-vector)
NIL

最新更新