可以将所有数据约束都表示为代数数据类型吗?

时间:2013-08-30 13:46:56

标签: haskell algebraic-data-types

数据和状态的所有约束都可以表示为代数数据类型吗?

我喜欢我经常能够将系统约束表达为ADT的方式。

即。 ADT的所有可能值都是系统的可能状态,不存在不一致的范围。

这种情况总是如此,还是存在无法表示为ADT的约束?

(换句话说,当我不能将一组约束表示为ADT时,是不是我看起来不够努力,或者某些类型的约束只能用ADT无法执行?)

有这方面的数学证明吗?


更新

这是一个玩具问题:

(roguelike)2D地图由方形单元组成,每个单元都有一种材料(岩石或空气)。

每个单元格有四个边界(N,S,E和W)。每个边界由两个单元共享。

只有当一侧是岩石而另一侧是空气时,边界可以选择性地包含“墙特征”。

(墙壁功能可以是杠杆,图片,按钮等)

当一面是摇滚而另一面是空气时,哪种ADT设计可以存储墙面特征?即,数据结构不能代表两个气囊或两个岩石细胞之间的边界上的壁特征。

1 个答案:

答案 0 :(得分:4)

对于状态有限的系统来说,情况确实如此:

data State = State1 | State2 | State3 | State4 | State5 | ...

但是具有无限数量状态的系统呢?如果我们仅限于编写有限的Haskell程序,那么只有相当多的Haskell程序,因此只有相当多的ADT。这是因为Haskell是一种用有限字母表编写的语言。

考虑以下数据类型,即位流:

data Stream = O Stream | I Stream

现在让我们开始在可以表示为Haskell数据类型的流上写下一些随机约束。 (所有这些必须可以表示为Haskell数据类型,或者已经存在无法在有限Haskell程序中由ADT表示的类型):

Type 0 admits every stream except OIOIOIOO...
Type 1 admits every stream except IIOOOIOI...
Type 2 admits every stream except OOOIOIIO...
Type 3 admits every stream except OOOOIIIO...
Type 4 admits every stream except OOIOIOOO...
Type 5 admits every stream except OOIOOOIO...
Type 6 admits every stream except IIOIOIIO...
Type 7 admits every stream except IIIIIIIO...
...

我们可以在Haskell中写下最多可数数量的此类数据类型,因为只有相当多的有限Haskell程序,并且每个有限的Haskell程序只能导出有限数量的没有类型变量的类型。使用类型变量导出类型的程序可能是程序的有趣子程序,它创建的类型是Stream的约束版本,但由于Stream没有类型变量,所有这些类型显然不是Stream的约束版本。 因此,如果我们可以证明存在许多可能的数据类型,那么必须存在至少一种Haskell ADT无法准确表示的类型。

让我们继续写下数据类型,直到我们将它们全部写入有限Haskell程序可以表示的所有数据类型的无限列表中。由于只有相当多的这些,它们可以映射到唯一的正整数,以便按顺序写下来。

现在,请考虑以下数据类型。它承认除了以相反位开头的流之外的每个流都是类型0未允许的流,其第二个位与第1类不允许的流的第二位相反,等等

类型x允许除IOIIOIOI之外的每个流...

这被称为康托尔的对角线。

Type x isn't Type 0, because it admits anything that starts with an O, and the only thing Type 0 excludes is one stream that starts with an O
Type x isn't type 1, because it admits anything that has a second bit of I, and the only thing Type 1 excludes is one stream that has a second but of I.
Type x isn't type 2, because it admits anything that has a third bit if O, and the only thing Type 2 excludes is one stream that has a third bit of O.
...

实际上,类型x不是我们写下的任何数据类型,我们写下了有限Haskell程序可以表示的每个数据类型,如Stream。因此,类型x不能由有限的Haskell程序表示。