Что является производным, который показывает \x -> (x, x) в Haskell, эквивалентный join (,)?
В соответствии с pointfree
:
\x -> (x, x)
эквивалентно:
join (,)
Какое происхождение показывает это?
2 ответа
Решение
Посмотрите на тип подписи:
\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.
Мне нравится Адиц, интуитивно понятный ответ. Вот как я могу это понять, прочитав исходный код.
- Я хожу в гугл
- Я ищу
join
- Я нажимаю на
join
- Я нажимаю кнопку "Исходный код", чтобы перейти к исходному коду
join
- я вижу это
join x = x >>= id
- Итак, я знаю, что
join (,) = (,) >>= id
- Я ищу
>>=
в Google и нажмите на ссылку - Я вижу, что это часть класса типов монада, и я знаю, что имею дело с
(,)
которая является функцией, поэтому я нажимаю "источник" наMonad ((->) r)
пример - я вижу это
f >>= k = \r -> k (f r) r
- Так как у нас есть
f = (,)
а такжеk = id
, мы получаем\r -> id ((,) r) r
- Ооочень... новая функция!
id
! Я ищу это в Google и нажимаю на его исходный код. - Оказывается
id x = x
- Так что вместо
join (,)
теперь у нас есть\r -> ((,) r) r
- Что то же самое, что
\r -> (,) r r
- Что то же самое, что
\r -> (r,r)
Никогда не забывайте, что Хэддокс ссылается на исходный код библиотеки. Это очень полезно при попытке выяснить, как все работает вместе.