2012-08-15 104 views
1

我试图使这种数据类型的Functor一个实例:是否无法创建此数据类型的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声明,但我试图更熟悉语言,所以任何帮助将不胜感激!

回答

8

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

你当然也可以只是重新定义Fraction是这样的:

data Fraction a = Frac a a deriving Show 

...或者你可以使用分数/有理数现有的数据类型Data.Ratio,不形成函子,因为没人认为有这样一个实例是有用的(反正你会用它什么?),但至少你会使用一个已经建立的和现有的数据结构。

+0

我正在建立一个小型图书馆进行某种锻炼。 'fmap'可能实际上甚至没有用处......我想这是一个很好的观点。 但是,无论如何,谢谢你的澄清!这帮助了我一堆。 – 2012-08-15 18:58:59

+1

我看到的'fmap'的唯一用途是它可以用于将分子和分母同时用一些常见的值进行划分,但这很容易做到。模式匹配。另外,我认为最大的缺点是没有明智的方法来实现'Fraction'的'pure',即使它仅限于使用'Integer'。为什么数字“1/1”特殊?为什么不用'0/12'或'42/1'?但是你可能对'Monoid'类和''algebra''(http://hackage.haskell.org/package/algebra)包中的各个类感兴趣。 – dflemstr 2012-08-15 19:03:48

+0

(对于代数包,您可能需要单击以前的版本才能阅读文档,因为最新版本会出现故障并缺少文档) – dflemstr 2012-08-15 19:05:04

相关问题