但是,您的问题确实提到了 满了,我认为一些问题出现在代码即数据方法上。类型存在于比表达式更抽象的级别。Lisp 没有这种区别——所有东西在结构上都是“扁平的”。如果我们考虑一个表达式 E: T (其中 T 是它的类型的一些表示) ,然后我们认为这个表达式是普通的 ol’数据,那么这里 T 的类型到底是什么?这是一种!A 是一个高阶类型,所以让我们继续在代码中讨论它:
If all you wanted was a statically typed language that 看起来像 Lisp, you could do that rather easily, by defining an abstract syntax tree that represents your language and then mapping that AST to S-expressions. However, I don't think I would call the result Lisp.
Calling the cons a list, though (1 2 3) looks like one, is a bit of a misnomer. For example, it's not at all comparable to a statically typed list, like C++'s std::list or Haskell's list. Those are single-dimensional linked lists where all the cells are of the same type. Lisp happily allows (1 "abc" #\d 'foo). Plus, even if you extend your static-typed lists to cover lists-of-lists, the type of these objects requires that 每个 element of the list is a sublist. How would you represent ((1 2) 3 4) in them?
type Symbol = String
data Atom = ASymbol Symbol | AInt Int | AString String | Nil
data Cons = CCons Cons Cons
| CAtom Atom
第一个问题是 Atom 类型的作用域。显然,我们还没有选择一种 Atom 类型的足够灵活性来覆盖我们希望在 conses 中悬挂的所有类型的对象。我们没有尝试扩展上面列出的 Atom 数据结构(您可以清楚地看到这种结构很脆弱) ,而是使用了一个神奇的类型类 Atomic来区分我们想要创建原子的所有类型。那么我们可以试试:
class Atomic a where ?????
data Atomic a => Cons a = CCons Cons Cons
| CAtom a