Есть ли в Prelude функция для сопряжения значения с этим значением, примененным к функции?
Я ищу функцию, которая выглядит примерно так:
withSelf :: (a -> b) -> a -> (a, b)
withSelf f x = (x, f x)
Я искал с помощью Google для такой функции; Я искал (a -> b) -> a -> (a, b)
а также a -> (a -> b) -> (a, b)
, ни один из которых не был убедительным. Страница Hackage на Data.Tuple
не имеет то, что я ищу тоже.
Я знаю, что писать тривиально, но я хочу написать идиоматический Haskell, где это возможно, и избегать повторного изобретения колеса.
2 ответа
Секция (id &&&)
делает то, что вы хотите:
> import Control.Arrow
> :t (id &&&)
(id &&&) :: (a -> c') -> a -> (a, c')
> (id &&&) succ 4
(4,5)
Если вы не хотите использовать Control.Arrow
, вы всегда можете использовать Applicative
:
withSelf f = (,) <$> id <*> f
Многие люди, вероятно, сразу поймут это, но для чего-то такого простого это довольно глупо.
редактировать
Как указано в комментарии, это можно записать еще более кратко, как
withSelf = ((,) <*>)
Сначала это удивило меня, но на самом деле все очень просто: (->) r
, fmap = (.)
, Итак <$> id
полностью излишним!