haskell - ghc 如何知道要使用 fmap 等的哪个定义?

标签 haskell types

我知道fmap类型为(a -> b) -> f a -> f b哪里f是一个仿函数(并且根据仿函数的不同做不同的事情)。我的基本问题是:给出一些调用 fmap r x , ghc 如何计算出仿函数 f 是什么?是,只要给出 x 的类型和r

让我说得更准确一些。假设ff'是仿函数使得 f a =f' a对于某些类型 a ,但是f bf' b是不同的。如果r类型为a -> bx类型为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/

相关文章:

haskell - 用延续单子(monad)向前跳跃

java - "Double"与 CompletableFuture 的组合

类型别名的 Go 类型开关

scala - 存在类型和重复参数

c++ - 具有模板特化的通用类型转换

c++ - 我可以在命名空间中重新定义内置类型吗?

javascript - 如何在严格评估的语言中实现 protected 递归?

haskell - 检查特定的数据构造函数

haskell - 如何使用免费的 monad 实现 Reader?

Haskell/Wreq - 关于 http 请求的复杂类型签名的建议