我是一个 Haskell 新手,所以如果答案很明显,我深表歉意,但我正在研究 Typeclassopedia,以更好地理解类别。在做仿函数部分的练习时,我遇到了这个问题:
Give an example of a type of kind * -> * which cannot be made an instance of Functor (without using undefined).
我的第一个想法是定义 fmap 的某种无限递归定义,但这本质上不会与定义中使用 undefined
相同吗?
如果有人能解释答案,我们将不胜感激。
谢谢!
原始练习来源,第 3 部分:http://www.haskell.org/haskellwiki/Typeclassopedia#Introduction
最佳答案
一个简单的例子是
data K a = K (a -> Int)
ghci 告诉我们的是,我们尝试自动派生 K
的 Functor
实例:
Prelude> :set -XDeriveFunctor
Prelude> data K a = K (a -> Int)
Prelude> :k K
K :: * -> *
Prelude> data K a = K (a -> Int) deriving Functor
<interactive>:14:34:
Can't make a derived instance of `Functor K':
Constructor `K' must not use the type variable in a function argument
In the data type declaration for `K'
问题是标准的Functor
类实际上代表协变仿函数(fmap
将其参数提升为f a -> f b
),但是你无法组合 a -> b
和 a -> Int
来获得 b -> Int< 类型的函数
(参见拉蒙的回答)。但是,可以为逆变仿函数定义类型类:
class Contravariant f where
contramap :: (a -> b) -> f b -> f a
并使 K
成为它的一个实例:
instance Contravariant K where
contramap f (K g) = K (g . f)
有关 Haskell 中协变/逆变的更多信息,请参阅 here .
编辑:这也是 a nice comment on this topic来自 Reddit 上的克里斯·史密斯。
关于haskell - 具有 kind * -> * 的类型的示例,该类型不能是 Functor 的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16118414/