具有错误类型参数的Functor

时间:2017-07-04 10:25:58

标签: haskell

我有以下数据类型并已申请Functor实例:

data Company a b c = 
    DeepBlue a c
  | Something b

instance Functor (Company a b) where 
  fmap f (Something b) = Something b
  fmap f (DeepBlue a c) = DeepBlue a (f c)

编译时没有任何抱怨。

然后我玩了一下(我知道它不起作用),因为初学者的好奇心:

data Company a b c = 
    DeepBlue a c
  | Something b

instance Functor (Company a b) where 
  fmap f (Something b) = Something (f b)
  fmap f (DeepBlue a c) = DeepBlue a (f c) 

然后编译器抱怨:

D:\haskell\chapter16\src\ChapterExercises.hs:18:26: error:
    * Couldn't match type `b1' with `b'
      `b1' is a rigid type variable bound by
        the type signature for:
          fmap :: forall a1 b1.
                  (a1 -> b1) -> Company a b a1 -> Company a b b1
        at D:\haskell\chapter16\src\ChapterExercises.hs:18:3
      `b' is a rigid type variable bound by
        the instance declaration
        at D:\haskell\chapter16\src\ChapterExercises.hs:17:10
      Expected type: Company a b b1
        Actual type: Company a b1 b1
    * In the expression: Something (f b)
      In an equation for `fmap': fmap f (Something b) = Something (f b)
      In the instance declaration for `Functor (Company a b)'
    * Relevant bindings include
        b :: b
          (bound at D:\haskell\chapter16\src\ChapterExercises.hs:18:21)
        f :: a1 -> b1
          (bound at D:\haskell\chapter16\src\ChapterExercises.hs:18:8)
        fmap :: (a1 -> b1) -> Company a b a1 -> Company a b b1
          (bound at D:\haskell\chapter16\src\ChapterExercises.hs:18:3)

D:\haskell\chapter16\src\ChapterExercises.hs:18:39: error:
    * Couldn't match expected type `a1' with actual type `b'
      `b' is a rigid type variable bound by
        the instance declaration
        at D:\haskell\chapter16\src\ChapterExercises.hs:17:10
      `a1' is a rigid type variable bound by
        the type signature for:
          fmap :: forall a1 b1.
                  (a1 -> b1) -> Company a b a1 -> Company a b b1
        at D:\haskell\chapter16\src\ChapterExercises.hs:18:3
    * In the first argument of `f', namely `b'
      In the first argument of `Something', namely `(f b)'
      In the expression: Something (f b)
    * Relevant bindings include
        b :: b
          (bound at D:\haskell\chapter16\src\ChapterExercises.hs:18:21)
        f :: a1 -> b1
          (bound at D:\haskell\chapter16\src\ChapterExercises.hs:18:8)
        fmap :: (a1 -> b1) -> Company a b a1 -> Company a b b1
          (bound at D:\haskell\chapter16\src\ChapterExercises.hs:18:3)
Failed, modules loaded: none.

编译器尝试说什么?

2 个答案:

答案 0 :(得分:6)

您已将Company声明为具有三种通用类型abc的类型。当您创建实例instance Functor (Company a b)时,您已经对任何ab说过,应该存在一个类型为的函数fmap

(c -> d) -> Company a b c -> Company a b d

函数f的类型为c -> d,因此您无法使用b作为输入,因为它没有正确的类型。< / p>

答案 1 :(得分:2)

您对fmap的定义有类型

fmap :: Company a b c -> (c -> d) -> Company a b d

因此该函数采用类型c的值。在

fmap f (Something b) = Something (f b)

您正在尝试将函数c -> d应用于导致错误的b类型的值。消息中的实际类型变量具有不同的名称:a1cb1d