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

21

根据 pointfree 的说法:

\x -> (x, x)

等价于:

join (,)

这个结果如何推导出来的?

2个回答

30

看类型标记:

\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)

证毕。


24
我喜欢Aadit的直观回答。以下是我通过阅读源代码来解决问题的方法。
  1. 我打开 Hoogle 网站
  2. 我搜索 join 的相关信息
  3. 点击 join
  4. 我点击“源代码”按钮,以获取 join 的源代码
  5. 我看到 join x = x >>= id
  6. 所以我知道 join (,) = (,) >>= id
  7. 我在 Hoogle 上 搜索 >>= 并点击链接
  8. 我发现它是单子类型类的一部分,并且我正在处理函数 (,),所以我 点击 Monad ((->) r) 实例上的 "源代码" 按钮
  9. 我看到 f >>= k = \r -> k (f r) r
  10. 由于我们有 f = (,)k = id,所以我们得到 \r -> id ((,) r) r
  11. 所以...新函数!id!我在 Hoogle 上搜索它,然后 点击进入其源代码
  12. 结果发现 id x = x
  13. 因此,我们现在有 \r -> ((,) r) r,而不是 join (,)
  14. 这与 \r -> (,) r r 相同
  15. 这与 \r -> (r,r) 相同
永远不要忘记,Haddocks链接到库的源代码。当试图弄清楚如何使事物协同工作时,这非常有用。

4
对于初学者来说,这很不错。写这种类型的答案对于新手来说非常有用。 - Benjamin Gruenbaum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接