阅读“程序员的分类理论”,我试图重新创建函子类型实例。
{-# LANGUAGE TypeSynonymInstances #-}
module Type.Op where
import Data.Functor.Contravariant ( Contravariant, contramap )
type Op r a = a -> r
-- data Op r a = (->) a r
instance Contravariant (Op r) where
contramap f g = g . f编译会产生以下错误:
• The type synonym ‘Op’ should have 2 arguments, but has been given 1
• In the instance declaration for ‘Contravariant (Op r)’
|
10 | instance Contravariant (Op r) where
| ^^^^^^^^^^^^^^^^^^^^我该怎么办?对于正常的Functor,我会以同样的方式使用部分类型..。
发布于 2021-11-02 22:07:27
让我们考虑一个更简单的类
class Unftor f where
unfmap :: (a -> a) -> f a -> f a
instance Unftor ((->) x) where
unfmap f g = f . g现在,如果你想做的事情是可能的,我也可以写
instance Unftor (Op r) where
unfmap f g = g . f...but等等,让我们看看每种情况下的签名
instance Unftor ((->) x) where
unfmap :: (a -> a) -> (x -> a) -> (x -> a)
instance Unftor (Op r) where
unfmap :: (a -> a) -> Op r a -> Op r a因为Op只是一个类型的同义词,所以它与
instance Unftor (\a -> (a -> r)) where
unfmap :: (a -> a) -> (a -> r) -> (a -> r)现在,选择所有类型都是Int的特例,
unfmap :: (Int -> Int) -> (Int -> Int) -> (Int -> Int)
unfmap f g = f . g -- from `instance Unftor ((->) x)`
unfmap :: (Int -> Int) -> (Int -> Int) -> (Int -> Int)
unfmap f g = g . f -- from `instance Unftor (Op r)`...the相同的签名!但不知何故编译器应该把它们分开??
那不管用。
相反,您需要做的是使Op成为一个仅与a -> r同构的可区分的类型。这正是新类型存在的原因(data也会工作):
newtype Op r a = Op {getOp :: a -> r}
instance Contravariant (Op r) where
contramap (Op f) g = Op $ g . fhttps://stackoverflow.com/questions/69816988
复制相似问题