Haskell的\x -> (x, x)等价于join(,)的推导是什么?

What is the derivation that shows Haskell's \x -> (x, x) equivalent to join (,)?

根据pointfree

\x -> (x, x)

相当于:

join (,)

说明这个的推导是什么?

查看类型签名:

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

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

join         :: Monad m => m (m a) -> m a

需要注意的是((->) r)Monad类型类的一个实例。因此,关于专业化:

join         :: (r -> r -> a) -> (r -> a)

join 对函数的作用是将给定函数两次应用于同一参数:

join f x = f x x

-- or

join f = \x -> f x x

由此,我们不难看出:

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

-- or

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

Qed.

我喜欢 Aadits 直观的回答。下面是我通过阅读源代码得出的结论。

  1. 我去Hoogle
  2. 我搜索join
  3. click on join
  4. 我点击 "source" 按钮进入 the source code for join
  5. 我看到 join x = x >>= id
  6. 所以我知道 join (,) = (,) >>= id
  7. search for >>= on Hoogle and click the link
  8. 我看到它是 monad 类型类的一部分,我知道我正在处理 (,) 这是一个函数,所以我 click "source" on the Monad ((->) r) instance
  9. 我看到 f >>= k = \r -> k (f r) r
  10. 因为我们有 f = (,)k = id,我们得到 \r -> id ((,) r) r
  11. 太棒了……新功能! id!我在 Hoogle 和 click through to its source code
  12. 上搜索
  13. 原来是 id x = x
  14. 所以我们现在 \r -> ((,) r) r
  15. 而不是 join (,)
  16. 这与 \r -> (,) r r
  17. 相同
  18. 这与 \r -> (r,r)
  19. 相同

永远不要忘记 Haddocks link 通过库的源代码。这在试图弄清楚事物如何协同工作时非常有用。