Какой самый короткий способ выразить функцию
f(a,b)(c,d)=(a+c,b+d)
в бессмысленной нотации?
pointfree.io дает нам
uncurry (flip flip snd . (ap .) . flip flip fst . ((.) .) . (. (+)) . flip . (((.) . (,)) .) . (+))
который с небольшим трудом может быть сокращен до
uncurry$(`flip`snd).((<*>).).(`flip`fst).((.).).(.(+)).flip.(((.).(,)).).(+)
для 76 байтов. Но это все еще кажется действительно длинным и сложным для такой простой задачи. Есть ли способ, которым мы можем выразить парное сложение как более короткую бессмысленную функцию?
Чтобы было ясно, что я имею в виду под бессмысленным объявлением, бессмысленное объявление функции включает в себя взятие существующих функций и операторов и применение их друг к другу таким образом, что создается желаемая функция. Обратные кавычки, скобки и буквальные значения ( []
, 0
, [1..3]
и т.д.) допускается , но ключевые слова , как where
и let
нет. Это означает:
Вы не можете назначать какие-либо переменные / функции
Вы не можете использовать лямбды
Вы не можете импортировать
(+)***(+)
.(+)<$>([1],2)<*>([3],4)
дает([1,3],6)
.Ответы:
44 байта
Получил это от
\x y -> (fst x + fst y, snd x + snd y)
Попробуйте онлайн!
источник
44 байта
-8 байт благодаря Орджану Йохансену. -3 байта благодаря Брюсу Форте.
Попробуйте онлайн!
Переводится на:
67 байт
-8 байт благодаря Орджану Йохансену. -1 байт благодаря Брюсу Форте.
Если требуется вывод кортежа:
Попробуйте онлайн!
Да, я, делая это вручную, не дает спелых фруктов. Но я доволен
[a] → (a, a)
преобразованием.Теперь, если была короткая функция с
m (a → b) → a → m b
.источник
mapM id[fst,snd]
короче.mapM id
это версия функции для гольфа, которую вы, вероятно, ищетеsequence
.(<*>)
подпись, которая естьm (a → b) → m a → m b
. Так близко ...Control.Lens.??
, что, возможно , было предложено для включения в базу в какой-то момент.(.mapM id[fst,snd])
подобноеlet r=(.mapM id[fst,snd]) in r(r.zipWith(+))
, но я не смог заставить проверку типов принять бессмысленную версию.54 байта
Я искренне сомневаюсь, что мы победим 44-байтовое решение @ H.PWiz, но никто не использовал тот факт, что
(,)
реализует класс типовFunctor
, так что вот еще один интересный, который не так уж плох:Попробуйте онлайн!
объяснение
Реализация класса типов
Functor
для 2- кортежей очень похожа на реализацию изEither
(из base-4.10.1.0 ):Для этой задачи это означает, что следующая функция добавляет вторые элементы, сохраняя первый элемент второго аргумента:
Так что, если бы у нас был какой-то маленький помощник,
helpPlz = \a b -> (fst a+fst b,snd b)
мы могли бы сделать(helpPlz<*>).flip(fmap.(+).snd)
и сделали бы. К счастью, у нас есть инструмент,pointfree
который дает нам:Таким образом, просто подключив эту функцию обратно, мы приходим к вышеуказанному решению (обратите внимание на то,
(<*>) = ap
что находится в базе ).источник
60 байт
Я не вижу
uncurry
здесь никакой любви, поэтому я решил заскочить и исправить это.Я думал, что при всех
fst
иsnd
, что распаковка аргументовuncurry
может дать некоторые результаты. Понятно, что это было не так плодотворно, как я надеялся.источник
uncurry
это так многословно. :( Но вы можете заменить крайние скобки на$
.