在Common Lisp中,如何定义通用数据类型说明符(如整数列表)? [英] In Common Lisp, how to define a generic data type specifier (like list of integers)?

查看:153
本文介绍了在Common Lisp中,如何定义通用数据类型说明符(如整数列表)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想定义一个类型说明符,用于描述相同类型的事物的列表。所以我想要(整数列表)(数组整数)(内置)相似)。我可以为特定类型创建它,例如:

I would like to define a type specifier that describes a list of things of the same type. So I would like to have (list-of integer) similar to (array integer) (which is built-in). I am able to create it for a specific type, like this:

(defun elements-are-integer (seq) 
  (every #'(lambda (x) (typep x 'integer)) seq))
(deftype list-of-integer ()
  '(and list (satisfies elements-are-integer)))

但是,这意味着我必须对每种可能的类型都要这样做。如何更改此代码,以便该类型将另一个类型用作参数,并动态构造 satisfies 谓词?问题是 satisfies 需要一个全局符号,而且我不知道如何在适当的上下文中定义谓词函数(我想我需要 gensym ,但是如何?)。另外,该解决方案应该可以起作用,以便可以在另一个包中创建类型。

However, this means I have to do this for every possible type. How can I change this code so that the type would take another type as an argument, and construct the satisfies predicate on the fly? The problem is that the satisfies requires a global symbol, and I don't know how to define the predicate function in proper context (I guess I need to gensym it somehow, but how?). Also, the solution should work so that the type could be created inside another package.

推荐答案

请尝试以下操作:

(defun elements-are-of-type (seq type)
  (every #'(lambda (x) (typep x type)) seq))

(deftype list-of-type (type)
  (let ((predicate (gensym)))
    (setf (symbol-function predicate)
      #'(lambda (seq) (elements-are-of-type seq type)) )
    `(and list (satisfies ,predicate)) ))

(typep '(1 2 3) '(list-of-type integer))
; -> T

(typep '(1 2 a) '(list-of-type integer))
; -> NIL

(typep '(a b c) '(list-of-type symbol))
; -> T

这篇关于在Common Lisp中,如何定义通用数据类型说明符(如整数列表)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆