为什么Functor的此举不起作用?

时间:2018-08-31 22:08:37

标签: haskell

为了避免与Prelude发生冲突,我定义了自己的Functor类:

class F f where
    fm :: (a -> b) -> f a -> f b

这为什么起作用...

instance F ((->) a) where
    fm g f = g . f

GHCI:

*Main> fm (+1) (+10) $ 100
111

...但这不是吗?

instance F ((->) Int) where
    fm g f = g . f

我不明白-我将基础集限制为Int映射的函数,这与Functor的机制/定义无关吗?

该错误消息无济于事:

    • Illegal instance declaration for ‘F ((->) Int)’
        (All instance types must be of the form (T a1 ... an)
         where a1 ... an are *distinct type variables*,
         and each type variable appears at most once in the instance head.
         Use FlexibleInstances if you want to disable this.)
    • In the instance declaration for ‘F ((->) Int)’
  |
4 | instance F ((->) Int) where
  |          ^^^^^^^^^^^^

1 个答案:

答案 0 :(得分:3)

是的,只要打开该if扩展名,它 就能足够肯定地工作。

-XFlexibleInstances

没有扩展名就无法工作的原因是标准的Haskell对实例所允许的内容有一个奇怪的限制。如果您不将实例特定于特定的参数类型,那么它实际上可以在Haskell98中使用:

{-# LANGUAGE FlexibleInstances #-}
class F f where fm :: (a -> b) -> f a -> f b
instance F ((->) Int) where fm g f = g . f

我认为这真的很愚蠢。因此instance F ((->) a) where fm g f = g . f 扩展名非常广泛,实际上我几乎在每个模块中都使用它。这是没有争议的。