什么';Haskell中“fmap”在谓词集合上的含义是什么?
我为Haskell编程所做的学生作业包括一项我有点困惑的任务。事情是这样给出的:仅为基于集合的新类型创建Functor类的实例。声明如下:什么';Haskell中“fmap”在谓词集合上的含义是什么?,haskell,functional-programming,functor,Haskell,Functional Programming,Functor,我为Haskell编程所做的学生作业包括一项我有点困惑的任务。事情是这样给出的:仅为基于集合的新类型创建Functor类的实例。声明如下: newtype Set x = Set { contains :: (x -> Bool) } 对于我来说,这是一个理解如果fmap应用于一组谓词的例子。在执行以前的任务时,我已经定义了fmap,而不是使用(+3)(改变整数)、(touper)(到字符串)等函数。这是我第一次处理正常类型以外的任何东西(各种数字、字符串、字符)。我谦虚地试图开始: i
newtype Set x = Set { contains :: (x -> Bool) }
对于我来说,这是一个理解如果fmap
应用于一组谓词的例子。在执行以前的任务时,我已经定义了fmap
,而不是使用(+3)
(改变整数)、(touper)
(到字符串)等函数。这是我第一次处理正常类型以外的任何东西(各种数字、字符串、字符)。我谦虚地试图开始:
instance Functor Set where
fmap f (Set x) = if (contains x) == True then Set (f x) else Set x
当然,这是一个无意义的代码,但我认为在
fmap
应用程序正常运行之前,需要评估一些真/假。但是,首先,请您解释一下谓词集的问题,以详细说明更合理的方法 使用此定义,实际上不可能为Set
定义Functor
实例。这是因为您的设置a
类型包含的a
处于负值位置。。。也就是说,a
是函数的参数,而不是值。发生这种情况时,类型构造函数可以是逆变函子(来自逆变
包的类型类逆变
),但不能是协变函子(逆变函子类型类)
以下是这些类的定义:
类函子f,其中
fmap::(a->b)->f a->f b
类逆变式f,其中
对比图::(a->b)->f b->f a
看到区别了吗?在逆变函子中,当提升函数以对函子类型进行操作时,传递的函数的方向会翻转
最后,这应该是有道理的。你对“集合”的概念是一个测试,它告诉你某样东西是否合格。这是一个非常好的集合的数学定义,但它提供了不同于标准集合的计算能力。例如,您无法获取基于谓词的集合的元素;只等待被给予一个潜在的元素。如果您有一个Set Integer
,和一个函数f::String->Integer
,那么您可以通过首先将它们转换为Integer
s并测试它们来测试String
,这样您就可以从Set Integer
到Set String
。但是拥有一个g::Integer->String
不能让你测试字符串
如果这是一项作业,那么要么你误解了作业,要么你做了一些与预期不同的早期步骤(例如,如果你在早期部分定义了
Set
你自己,也许你需要更改定义),或者,你的导师希望你能解决这个问题,并理解为什么不能定义函子。你说的是“谓词集”,但从来没有提到“谓词集”部分。我有预感这可能很重要。什么是PSet
?什么是PSet
Set
是一个围绕特征函数的包装器,因此,例如,Set-偶数
表示偶数集:给定e=Set-偶数
,您可以通过计算包含e x
:包含e 2==True
和包含e 3==False
来确定值,比如说PSet
看起来像是幂集的数据构造函数,因此contains x
只会为集合x
提供特征函数,而不是布尔值。很抱歉,与新类型声明中的set
不同,PSet
出现错误。这看起来是正确的,除非注意到我简陋的代码,事实上…@chepner,谢谢你的建议,我会按照你的解释进行。现在,这对我来说似乎更为明显。非常感谢您分享的见解,非常值得欣赏,以及任何能够更好理解的东西……让我们看看,我当然没有忽略任何重要的细节来提供集合代码。也许,这只是一个测试我们关于函子的原因的例子。现在我很可能会更好地看到这一点,我有必要问我的问题。