4

我知道它fmap的类型(a -> b) -> f a -> f bwhere fis a functor (并且根据函子的不同做不同的事情)。我的基本问题是这样的:给定一些调用fmap r x,ghc 如何找出函子f是什么,只是给定了xand的类型r

让我更准确地说。假设ff'是这样的函子,对于某些类型f a= ,但是和是不同的。如果has type和has type ,似乎有两种不同的可能结果:something of type和 something of type 。这种歧义是如何解决的?f' aaf bf' bra -> bxf afmap r xf bf' b

第二个问题:我想通过制作一个奇怪的函子来测试这一点——也许a[Int]任何类型都适用a并对函数做一些愚蠢的事情……但我显然还没有找到合适的语法让我以这种方式指定函子。(有类似的东西data Newtype a = [Int]吗?看来我需要先创建一个类型类名称才能使其成为仿函数的实例。)

编辑:我现在明白了,但为了记录,真正的问题(这只是我的问题中隐含的)是我没有意识到你不能拥有一个Foo类似已经存在Foo a的类型的函子。Int

4

4 回答 4

2

我认为您正在寻找的一般答案是 Haskell 类型是使用“种类”组织的,类似于类型的类型。

这是Functor课程

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

它不是显式的,但这意味着它f是一个带有 kind 的类型构造函数* -> *。只有具有那种类型的类型才能成为Functors。

这实际上是一个相当强烈的声明。这意味着 anyFunctor在类型参数中必须是参数的。现在考虑你的陈述:

假设 f 和 f' 是函子,对于某些类型 a,fa = f' a,但 fb 和 f' b 是不同的。

鉴于善良的系统,这是不可能的。由于 aFunctor在其类型参数中是参数的,因此f a = f' a意味着。f = f'f b = f' b

Functor我不完全确定您对“奇怪的函子”的要求是什么,但这听起来像是类型类无法表达的东西。IIRCFunctor只能在 Hask 上表达 endofunctors;您可能需要不同的抽象来允许类别之间的函子。

于 2013-08-13T17:29:29.903 回答
1

Haskell 类型类基于一阶逻辑解析。类型变量上的类型类约束是该逻辑系统中的谓词(如果您曾经尝试在需要类型名称的地方使用类型类名称,您可能会看到指示这一点的错误消息)。

Haskell 要求整个程序中的每个 (Predicate, Type) 对都有一个唯一的解决方案,因此例如,您将无法在 Int 上创建两个不同的 Functor 实例。解决此问题的标准方法,例如在 Monoid 类中用于数字类型,根据您定义要使用的 monoidal 运算符的方式,可以提供求和或乘积,是在newtype您希望类的具体类型上提供包装器有不同的实例。

所以,对于Monoid,我们有newtype Sum a = Sum { getSum :: a }instance Num a => Monoid (Sum a)对于和幺半群,newtype Product a = Product { getProduct :: a }对于instance Num a => Monoid (Product a)积幺半群,我们有和。

请注意,由于type只为一个类型创建别名,因此为一个类型提供多个类实例是不够的。newtype声明在某种意义上类似于它type不会为新类型生成任何额外的运行时结构,但它的不同之type处在于它创建一个新类型而不是类型别名。

于 2013-08-13T19:53:44.227 回答
0

这取决于你通过什么论据。例如,列表是函子,因此也是Maybe

main = do
   putStrLn $ show (double [1..5])
   putStrLn $ show (double (Just 3))
   putStrLn $ show (double Nothing)

double :: (Functor f, Num a) => f a -> f a
double = fmap (*2)

*Main> main
[2,4,6,8,10]
Just 6
Nothing

double函数适用于任何持有Num.

于 2013-08-13T17:02:31.030 回答
0

“假设ff'是函子,这样f a=f' a对于某种类型a,但f bf' b是不同的。”

这真的没有意义。或者ff'是相同的,或者它们不是。您似乎在暗示某种中间状态,它根据参数类型而有所不同;那不可能发生。

“如果rhas typea -> bxhas type f a,似乎有两种不同的可能结果fmap r x:something of typef b和 something of type f' b。这种歧义是如何解决的?”

是从哪里来f'的?上述签名中没有提到它。由于xhas 类型f a,因此 的结果fmap必须具有某种以f- 开头的类型,在这种情况下f b,since r :: a -> b。这是完全明确的。的结果fmap始终与您开始时同一个函子中。

于 2013-08-13T17:19:41.837 回答