我知道fmap
类型为(a -> b) -> f a -> f b
哪里f
是一个仿函数(并且根据仿函数的不同做不同的事情)。我的基本问题是:给出一些调用 fmap r x
, ghc 如何计算出仿函数 f
是什么?是,只要给出 x
的类型和r
?
让我说得更准确一些。假设f
和f'
是仿函数使得 f a
=f' a
对于某些类型 a
,但是f b
和f' b
是不同的。如果r
类型为a -> b
和x
类型为f a
,似乎 fmap r x
有两种不同的可能结果:某种类型的东西f b
和类似的东西f' b
。如何解决这种歧义?
第二个问题:我想通过制作一个奇怪的仿函数来测试这一点 - 也许需要 a
至[Int]
适用于任何类型 a
并对函数做了一些愚蠢的事情...但我显然还没有找到允许我以这种方式指定仿函数的正确语法。 (有类似 data Newtype a = [Int]
这样的东西吗?看来我需要先创建一个类型类名称,然后才能将其设为仿函数的实例。)
编辑:我现在明白了,但郑重声明,真正的问题(仅隐含在我的问题中)是我没有意识到你不能有仿函数 Foo
这样Foo a
是类似 Int
的类型已经存在了。
最佳答案
我认为您正在寻找的一般答案是 Haskell 类型是使用“种类”来组织的,这就像类型的类型。
这是Functor
类
class Functor f where
fmap :: (a -> b) -> f a -> f b
它并不显式,但这意味着 f
是一个类型为 * -> *
的类型构造函数。只有具有这种类型的类型才能成为仿函数。
这实际上是一个相当强烈的声明。这意味着任何仿函数都必须是类型参数中的参数。现在考虑一下你的陈述:
Suppose f and f' are functors such that f a = f' a for some type a, but f b and f' b are different.
考虑到这种系统,这是不可能的。由于 Functor
的类型参数是参数化的,因此 f a = f' a
意味着 f = f'
,因此 f b = f' b
.
我不完全确定您对“奇怪的仿函数”的要求是什么,但它听起来像是无法用 Functor
类型类表达的东西。 IIRC Functor
只能在 Hask 上表达 endofunctor;您可能需要一个不同的抽象来允许类别之间的仿函数。
关于haskell - ghc 如何知道要使用 fmap 等的哪个定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18214621/