我正在尝试为这种类型编写一个fmap
data Triangle a = Triangle {t0 :: Point a, t1 :: Point a, t2 :: Point a}
Run Code Online (Sandbox Code Playgroud)
其中Point定义为
data Point a = Point {px :: a, py :: a, pz :: a}
Run Code Online (Sandbox Code Playgroud)
而我的实例def是
instance Functor Triangle where
fmap f (Triangle v0 v1 v2) = Triangle (f v0) (f v1) (f v2)
Run Code Online (Sandbox Code Playgroud)
我收到以下恭维错误,我无法弄清楚为什么
C:\Scripts\Haskell\Geometry.hs:88:1:
Occurs check: cannot construct the infinite type: a = Point a
When generalising the type(s) for `fmap'
In the instance declaration for `Functor Triangle'
有任何想法吗?
instance Functor Point where
fmap f (Point v0 v1 v2) = Point (f v0) (f v1) (f v2)
instance Functor Triangle where
fmap f (Triangle v0 v1 v2) = Triangle (fmap f v0) (fmap f v1) (fmap f v2)
Run Code Online (Sandbox Code Playgroud)
在Triangle实例中,f是a -> b.我们必须把它转换成Point a -> Point b第一个.然后我们可以fmap f转换Triangle a为Triangle b.(观察你正在申请f9件物品,如果我理解你的意图正确的话)[编辑:是27]
前面的答案为您提供了正确的解决方案,但更明确地了解这里发生的事情可能会有所帮助.类型fmap是
fmap :: Functor f => (a -> b) -> f a -> f b
Run Code Online (Sandbox Code Playgroud)
因此,您的instance声明的类型推断过程如下:
fmap f (Triangle v0 v1 v2),f必须有一些类型a -> b,(Triangle v0 v1 v2)必须有类型Triangle a.
Triangle,v0,v1,并且v2必须有类型Point a.f被施加到v0,v1以及v2,它的参数类型a必须是Point a.a = Point a不可满足.为什么定义Triangle (fmap f v0) (fmap f v1) (fmap f v2)有效?:
fmap f (Triangle v0 v1 v2),f必须有一些类型a -> b,(Triangle v0 v1 v2)必须有类型Triangle a.
Triangle,v0,v1,并且v2必须有类型Point a.Point是一个实例Functor,如上所述,fmap f v0必须具有类型Point b,其中b是结果类型f.同样的v1和v2.Triangle (fmap f v0) (fmap f v1) (fmap f v2)有类型Triangle b.