所述join
效用函数被定义为:
join :: (Monad m) => m (m a) -> m a
join x = x >>= id
Run Code Online (Sandbox Code Playgroud)
鉴于>>=
is Monad m => m a -> (a -> m b) -> m b
和id
is 的类型,a -> a
该函数如何也a -> m b
可以在上面的定义中输入?什么是m
与b
在这种情况下?
dav*_*420 14
a
类型中的s >>=
和id
不一定是相同的a
s,所以让我们重述这样的类型:
(>>=) :: Monad m => m a -> (a -> m b) -> m b
id :: c -> c
Run Code Online (Sandbox Code Playgroud)
因此,我们可以得出这样的结论c
是一样a
毕竟,至少当id
是第二个参数来>>=
......而且这c
是一样的m b
.所以a
是一样的m b
.换一种说法:
(>>= id) :: Monad m => m (m b) -> m b
Run Code Online (Sandbox Code Playgroud)
Lui*_*las 10
dave4420点击它,但我认为以下言论可能仍然有用.
有一些规则可用于将类型有效地"重写"为与原始类型兼容的另一种类型.这些规则涉及用其他类型替换所有出现的类型变量:
id :: a -> a
,你可以替换a
使用c
,并得到id :: c -> c
.后一种类型也可以重写为原始id :: a -> a
类型,这意味着这两种类型是等价的.作为一般规则,如果将类型变量的所有实例替换为原始中不存在的另一个类型变量,则会得到等效类型.id :: a -> a
,你可以改写它id :: Int -> Int
.然而,后者不能重写回原版,所以在这种情况下,你是专门的类型.f :: a -> m b
,则可以替换所有出现的a
with m b
和get 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)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
199 次 |
最近记录: |