根据Typeclassopedia和this link,类型只能有一个Functor
实例(链接中有证据)。但我的理解是,给定类型可能有多个可能的Monad
个实例,这是对的吗?但是对于给定的Monad
实例,有一个带有
Functor
实例
fmap f xs = xs >>= return . f
由此我得出结论,如果我偶然发现了一种我可以用不同方式定义多个Monad
实例的类型,那么上面派生的fmap
函数必须对所有这些实例都相等,换句话说,如果我有两对函数:
bind_1 :: m a -> (a -> m b) -> m b
unit_1 :: a -> m a
bind_2 :: m a -> (a -> m b) -> m b
unit_2 :: a -> m a
表示相同类型的构造函数m
,而不是必需:
xs `bind_1` (unit_1 . f) == xs `bind_2` (unit_2 . f)
适用于所有xs :: a
和f :: a -> b
。
这是真的吗?这是否作为一个定理?
答案 0 :(得分:17)
是。事实上,我们可以使用类型
的所有函数做出更强有力的陈述fmap :: (a -> b) -> (F a -> F b)
这样fmap id = id
是等价的。这实际上只是fmap
的类型与称为参数化的东西。
在您的情况下,如果>>=
和return
符合monad法律,那么
mFmap f a = a >>= return . f
mFmap id a = a >>= return . id
mFmap id a = a >>= return
mFmap id a = a
mFmap id = id
根据monad法律,a >>= return
只是a
。使用这个结果,我们可以诉诸我们从参数化得到的自由定理,我们有证据。