Aad*_*hah 30

看一下类型签名:

\x -> (x, x) :: a -> (a, a)

(,)          :: a -> b -> (a, b)

join         :: Monad m => m (m a) -> m a
Run Code Online (Sandbox Code Playgroud)

应该注意的((->) r)是,是Monad类型类的一个实例.因此,在专业化:

join         :: (r -> r -> a) -> (r -> a)
Run Code Online (Sandbox Code Playgroud)

什么join做的功能是两次申请给定函数相同的说法:

join f x = f x x

-- or

join f = \x -> f x x
Run Code Online (Sandbox Code Playgroud)

从这一点来看,我们可以轻松地看到:

join (,) = \x -> (,) x x

-- or

join (,) = \x -> (x, x)
Run Code Online (Sandbox Code Playgroud)

QED.


kqr*_*kqr 24

我喜欢Aadits的直观回答.这是我通过阅读源代码来弄清楚的.

  1. 我去霍尔格
  2. 我搜索 join
  3. 点击join
  4. 我单击"源"按钮以获取源代码join
  5. 我看到 join x = x >>= id
  6. 所以我知道 join (,) = (,) >>= id
  7. 搜索>>=上Hoogle并点击链接
  8. 我看到它是monad类型类的一部分,我知道我正在处理(,)哪个是函数,所以我Monad ((->) r)实例上单击"source"
  9. 我看到 f >>= k = \r -> k (f r) r
  10. 因为我们有f = (,)k = id,我们得到\r -> id ((,) r) r
  11. Sooo ...新功能!id!我在Hoogle上搜索它,然后点击它的源代码
  12. 结果 id x = x
  13. 所以join (,)我们现在没有\r -> ((,) r) r
  14. 这是一回事 \r -> (,) r r
  15. 这是一回事 \r -> (r,r)

永远不要忘记Haddocks链接到库的源代码.当试图弄清楚事物如何协同工作时,这非常有用.

  • 这对初学者来说很美.写这种答案对新手来说非常有用. (4认同)