首页 > 解决方案 > 在 Haskell 中,“fmap”对谓词集的含义是什么?

问题描述

我正在为 Haskell 编程做的学生作业包括一个我有点难以解决的任务。事情是这样给出的:为基于集合的新类型创建一个 Functor 类的实例。有这样的声明:

newtype Set x = Set { contains :: (x -> Bool) }

这是一个让我理解 iffmap用于诸如一组谓词之类的东西的含义的案例。在处理之前的任务时,我已经定义fmap了诸如(+3)(更改整数)、(toUpper)(转换为字符串)等函数。这是我第一次处理超出正常类型(各种数字、字符串、字符)的任何内容。我谦虚地尝试开始:

instance Functor Set where
    fmap f (Set x) = if (contains x) == True then Set (f x) else Set x

fmap当然,这是一个无意义的代码,但我想在应用顺利之前需要评估一些真/假。但是,首先,您能否解释一下谓​​词集的问题以阐述更明智的方法?

标签: haskellfunctional-programmingfunctor

解决方案


有了这个定义,实际上不可能为 定义一个Functor实例Set。这样做的原因是您的Set a类型包含a否定位置......也就是说,a它是函数的参数,而不是值。发生这种情况时,类型构造函数可以是逆变函子(包Contravariant中的类型类contravariant),但不能是协变函子(Functor类型类)。

以下是这些类的定义:

class Functor f where
    fmap :: (a -> b) -> f a -> f b

class Contravariant f where
    contramap :: (a -> b) -> f b -> f a

看到不同?在逆变函子中,您传入的函数的方向在它被提升以对函子类型进行操作时被翻转。

最后,这应该是有道理的。您对“集合”的概念是一种测试,它告诉您某物是否合格。这是对集合的完美数学定义,但它为您提供了与标准不同的计算能力。例如,您无法获取基于谓词的集合的元素;只能等待被赋予潜在元素。如果你有一个Set Integer, 和一个函数f :: String -> Integer,那么你可以String通过首先将它们转换为Integers 并测试它们来测试 s ,这样你就可以 Set Integer Set String。但是拥有一个g :: Integer -> String并不能让你测试Strings

如果这是一个作业,那么要么你误解了作业,你做了一些与预期不同的更早的步骤(例如,如果你Set在前面的部分定义了自己,也许你需要更改定义),或者你的导师希望您会为此奋斗并理解为什么Functor无法定义。


推荐阅读