不确定我在Haskell中理解这种类型

时间:2016-03-05 14:06:43

标签: haskell types functional-programming

好的,为了继续my previous questions,我有一个名为Enumeration的类型,它被描述为

  

现在,枚举是有限桶的无限序列,   用自然数索引

定义如下:

> type Nat = Int 
> type Enumeration a = Nat -> Finite a

这是Finite Bucket

> type Finite a = [a]

因此,如果我理解正确,Enumeration就像列表一样?它是一个从Int到列表的函数,它应该像索引一样使用int,并返回一个列表。

但我无法理解的是,它是否确实是一个列表列表,它在哪里存储它"列表"所以它可以稍后使用我提供的index返回它们。

我已经在此Enumeration类型上定义了一些功能,但我不确定它们是否正确,因为我不确定我是否真的理解了Enumeration

例如:

定义一个函数来进行单例枚举。 为简单起见,我建议您将唯一的项目放入存储桶0中。

> singleE' :: a -> Enumeration a
> singleE' a 0 = singleF a

定义枚举映射:

> imapE :: (a -> b) -> Enumeration a -> Enumeration b
> imapE f g = (imapF f) . g

定义枚举的不相交联合:

  

为简单起见,您可以逐桶执行此操作:结果枚举的存储桶i中的项目应该从存储桶i中获取   两个参数枚举。

> plusE :: Enumeration a -> Enumeration b -> Enumeration (Either a b)
> plusE f g = \n -> [Left x | x <- f n] ++ [Right y | y <- g n]

定义枚举的笛卡尔积

  

这比较棘手,因为你不能再一桶一桶了,   正如你为plusE所做的那样(为什么不呢?)。最简单的技术就是执行   一种卷积:结果枚举的桶i中的项目   应该从第一个论点的第j栏中的那些构造出来   并且在第二个桶k中,其中j + k = i。

> timesE :: Enumeration a -> Enumeration b -> Enumeration (a,b)
> timesE f g = \n -> timesF (f n) (g n)

所以我的问题是:

  1. 我是否正确理解了Enumeration的类型

  2. 如果我这样做,我定义的函数是否正确?

1 个答案:

答案 0 :(得分:2)

我们可以证明Enumeration a(大多数)与列表列表同构。 &#34;同构&#34;由以下函数给出:

enumerationToLists :: Enumeration a -> [[a]]
enumerationToLists f = map f [0..]

listsToEnumeration :: [[a]] -> Enumeration a
listsToEnumeration xss i = head $ drop i (xss++empties)

其中:

empties :: [[a]]
empties = []:empties

由于引用透明度,我们可以使用&#34;等式推理&#34;就像在数学中所做的那样,证明它们确实形成了一种同构性,并且#34;

证明listsToEnumeration . enumerationToLists = id

    (listsToEnumeration . enumerationToLists) f
by definition of .
    = listsToEnumeration (enumerationToLists f)
by definition of enumerationToLists
    = listsToEnumeration (map f [0..])
by definition of map
    = listsToEnumeration [f 0, f 1, f 2, ...]
by definition of listsToEnumeration
    = \i -> head $ drop i ([f 0, f 1, f 2, ...]++empties)
concatenation of infinite lists
    = \i -> head $ drop i [f 0, f 1, f 2, ...]
by definition of drop and of the argument
    = \i -> head $ [f i, f (i+1), f (i+2), ...]
by definition of head
    = \i -> f i
eta reduction  (i.e. \x -> f x = f)
    = f

现在,鉴于xss = [xs1, xs2, ..., xsN]empties = []:empties,我们有(enumerationToLists . listsToEnumeration) (xss++empties) = xss++empties

    (enumerationToLists . listsToEnumeration) (xss++empties)
by definition of .
    = enumerationToLists (listsToEnumeration (xss++empties))
by definition of listsToEnumeration
    = enumerationToLists (\i -> head $ drop i (xss++empties++empties))
concatenation of infinite lists
    = enumerationToLists (\i -> head $ drop i (xss++empties))
by definition of empties
    = enumerationToLists (\i -> head $ drop i [xs1, xs2, ..., xsN, [], [], ...])
by definition of enumerationToLists
    = map (\i -> head $ drop i [xs1, xs2, ..., xsN, [], [], ...]) [0..]
by definition of map
    = let f = (\i -> head $ drop i [xs1, xs2, ..., xsN, [], [], ...]) in [f 0, f 1, ...]
by definition of f
    = [head $ drop 0 [xs1, xs2, ..., xsN, [], ...], head $ drop 1 [xs1, xs2, ..., xsN, [], ...], ...]
by definition of drop
    = [head [xs1, xs2, xsN, [], ...], head [xs2, ... xsN, [], ..], ..., head [xsN, [],...], head [[], ...], ..]
by definition of head
    = [xs1, xs2, ..., xsN, [], [], ...]
by definition of xss, empties and ++
    = xss ++ empties

显然,我们假设Enumeration a是总数(它应该返回[]用于&#34;未定义的索引&#34;)。如果我们限制列表的无限列表,则上面的两个函数是同构,否则它只保持&#34;直到++empties&#34; (如果xss是无限的,我们有xss = xss++empties,因为我们永远无法访问空帐部分。)

所以,如果你想保持这种同构性&#34;你应该确保所有的功能都是完整的(看singleE' ...),但除此之外他们看起来很好。

我希望上面的例子能说明如何判断你定义的函数是否正确。