2017-12-03 259 views
-2

所以我需要在Haskell中创建一个Set数据类型。创建Set数据类型

所以,我的问题的第一部分,我需要定义

type Set a = ... 

我把它设置为

type Set a = Set [a] 

因为套装也只是α的名单,对不对? 或者,将正确的方式做到这一点是

type Set a = ([a]) 

然后,在接下来的一部分,我需要实现的功能

setSuchThat :: (a -> Bool) -> (Set a) 

功能需要一个特征函数f并返回一组这样仅当f(x)为真时,值x(适当类型)才在该集合中。因此,它在使用中的例子是,

setSuchThat (\x -> x == "coke") 

所以我的问题是,现在,是该函数我基本上需要评估该功能让“可乐”,然后将其添加到我的设置。我想我只是不明白,在这个功能中,我会去做这件事。

+0

查找'filter'的源代码。你会发现'setSuchThat = filter'。 – Alec

+1

这将是不可能的。有无数的可能的字符串。程序如何知道它具有所有返回“真”的值?更现实的解决方案是使用'filter'。 – 4castle

+1

如果你唯一需要实现的功能是'setSuchThat',那么让我建议'输入Set a = a - > Bool'。你应该找到'setSuchThat'这个微不足道的东西。 –

回答

4

继丹尼尔·瓦格纳的建议,你可以定义一组作为谓语指示元素是否在集合:

type Set a = a -> Bool 

良好的措施,我将使用一个newtype,以使其更清晰这里我们使用集:

newtype Set a = Set { contains :: a -> Bool } 

然后setSuchThat只是包装一个谓语Set

setSuchThat :: (a -> Bool) -> Set a 
setSuchThat = Set 

您可以使用contains功能的一组测试成员:

> setSuchThat (== "coke") `contains` "coke" 
True 

> setSuchThat (== "coke") `contains` "pepsi" 
False 

所以空集只是setSuchThat (const False) - 对于任何给定的元素,它总是回答这个问题:“请问一套包含此元素?“ 没有”。

insert :: (Eq a) => a -> Set a -> Set a 
insert x s = Set $ \ x' -> x == x' || s `contains` x' 

> insert "pepsi" (setSuchThat (== "coke")) `contains` "pepsi" 
True 

union其他功能很容易:

然后你就可以实现诸如insert组成现有contains功能与新的功能扩展集新元素

union :: Set a -> Set a -> Set a 
union s1 s2 = Set $ \ x -> s1 `contains` x || s2 `contains` x 

> let sodas = setSuchThat (== "coke") `union` setSuchThat (== "pepsi") 

> sodas `contains` "coke" 
True 

> sodas `contains` "pepsi" 
True 

> sodas `contains` "water" 
False 

作为练习,请尝试执行其他设置功能,如delete,intersectdifference

此方法的一个缺点是每个查找都是线性-O(n) - 插入或删除元素的数量。此外,你不能简单地枚举集将其转换为A的所有元素列表中,你只能列举测试每一个是否是一个元素。不过,其中一个的优势就是让您轻松表示无限集;例如,setSuchThat (> 0)包含所有非负数。

这就是为什么标准Data.Set类型使用基于树的数据结构,而不是功能,代表元素,它们的实际值。用这种方法,值可在不增加集的大小被删除,并且,因为它使用Ord代替Eq,实现了更有效的对数O(log n)的-lookups和插入。

1

要建立在什么Jon Purdy打下了:

你需要考虑的Set a = a -> Bool的作为,你必须一起工作的限制。当您看到setSuchThat :: (a -> Bool) -> (Set a)时,您可以将其读取为与setSuchThat :: (Set a) -> (Set a)setSuchThat :: (a -> Bool) -> (a -> Bool)相同。 setSuchThat有点像一个mcguffin,它只是在那里使用更清晰的功能 - 这是没有必要的。你正在做

一切都是以功能f并将其应用到变量x。的setSuchThat整个的一点是要传递fx只有f x返回。