的join
效用函数被定义为:Haskell类型系统魔法允许定义连接吗?
join :: (Monad m) => m (m a) -> m a
join x = x >>= id
鉴于的>>=
类型是Monad m => m a -> (a -> m b) -> m b
和id
是a -> a
,如何能该功能也被分型为a -> m b
因为它必须是上面定义的?在这种情况下,m
和b
是什么?
的join
效用函数被定义为:Haskell类型系统魔法允许定义连接吗?
join :: (Monad m) => m (m a) -> m a
join x = x >>= id
鉴于的>>=
类型是Monad m => m a -> (a -> m b) -> m b
和id
是a -> a
,如何能该功能也被分型为a -> m b
因为它必须是上面定义的?在这种情况下,m
和b
是什么?
的a
S IN的类型>>=
和id
不一定相同a
S,让我们重申类型是这样的:
(>>=) :: Monad m => m a -> (a -> m b) -> m b
id :: c -> c
因此,我们可以得出结论:c
是一样a
毕竟,至少当id
是>>=
的第二个参数时......并且c
与m b
相同。所以a
与m b
相同。换句话说:
(>>= id) :: Monad m => m (m b) -> m b
dave4420撞击它,但我认为以下几点意见可能仍然是有用的。
有一些规则可以用来有效地将某个类型“重写”为与原始类型兼容的另一种类型。这些规则涉及到与一些其他类型的替换类型变量的所有出现:
id :: a -> a
,你可以用c
替代a
并获得id :: c -> c
。后一种类型也可以重写为原始的id :: a -> a
,这意味着这两种类型是等价的。作为一般规则,如果将所有类型变量的实例替换为原来无处不在的另一个类型变量,则会得到一个等效类型。id :: a -> a
,则可以将其重写为id :: Int -> Int
。但后者不能改写回原来的,所以在这种情况下,你是专门为的类型。f :: a -> m b
,则可以用m b
替换所有出现的a
,并获得f :: m b -> m b
。既然这个也不能撤消,这也是一个专业化。即最后一个例子示出了如何id
可以用作>>=
第二个参数。所以回答你的问题是,我们可以重写,并得出如下类型:
1. (>>=) :: m a -> (a -> m b) -> m b (premise)
2. id :: a -> a (premise)
3. (>>=) :: m (m b) -> (m b -> m b) -> m b (replace a with m b in #1)
4. id :: m b -> m b (replace a with m b in #2)
.
.
.
n. (>>= id) :: m (m b) -> m b (indirectly from #3 and #4)
会发生什么,如果'了'是'M B',如'id'迫使它呢?这应该回答你的问题。 – 2012-04-20 21:01:23
这种魔法的味道通常被称为“统一”:) – 2012-04-21 16:18:12