我正在尝试将此数据类型设为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
声明,但我正试图更熟悉这种语言,所以任何帮助都会受到赞赏!
答案 0 :(得分:8)
是的,你不能定义一个仿函数而没有一个类型变量来“遗漏”声明(或者更正式地说:一个仿函数实例必须为某种类型* -> *
定义)。 fmap
的签名为fmap :: (a -> b) -> f a -> f b
,因此为了满足该合同,必须为该函数选择任何类型a
和b
。
您当然可以将Fraction
重新定义为:
data Fraction a = Frac a a deriving Show
...或者你可以在Data.Ratio中使用现有的数据类型来获得分数/有理数,这不构成仿函数,因为没有人认为这样的实例是有用的(你会用它做什么)但是,无论如何?),但至少你会使用一个完善的现有数据结构。