是否无法创建此数据类型的Functor实例?

时间:2012-08-15 18:50:11

标签: haskell types functor fractions

我正在尝试将此数据类型设为Functor的实例:

data Fraction = Frac Integer Integer deriving Show

但是,像这样定义它将不起作用:

instance Functor Fraction where
  pure = Frac 1 1
  fmap f (Frac a b) = Frac (f a) (f b)

想要这个功能,我希望数据是Functor的一个实例。但是,这是否违反了某些法律,因为Fraction的参数总是两个Integers

我总是可以自己编写fmap并避免Functor声明,但我正试图更熟悉这种语言,所以任何帮助都会受到赞赏!

1 个答案:

答案 0 :(得分:8)

是的,你不能定义一个仿函数而没有一个类型变量来“遗漏”声明(或者更正式地说:一个仿函数实例必须为某种类型* -> *定义)。 fmap的签名为fmap :: (a -> b) -> f a -> f b,因此为了满足该合同,必须为该函数选择任何类型ab

您当然可以将Fraction重新定义为:

data Fraction a = Frac a a deriving Show

...或者你可以在Data.Ratio中使用现有的数据类型来获得分数/有理数,这不构成仿函数,因为没有人认为这样的实例是有用的(你会用它做什么)但是,无论如何?),但至少你会使用一个完善的现有数据结构。