Способ тройного сопряжения без точек

#haskell #pointfree

#хаскелл #без точек

Вопрос:

Вот функция, которая умножает первые два элемента трехэлементного кортежа:

 f (a, b, _) = a * b
 

Мне было любопытно, можно ли сделать эту функцию бесточечной. Для пары это было бы так же просто, как f = uncurry . (*) , и если бы у нас было что-то подобное tripleToPair , это сделало бы решение очевидным, но эта функция также написана самым простым способом, с помощью сопоставления с образцом.

Я спросил всемогущего pointfree.io , но он вернул ошибку 500. Возможно ли это вообще? Вопрос чисто теоретический, на мой взгляд, функция хороша и так.

Комментарии:

1. При переходе к без точек мы обычно выбираем разрешенный набор примитивов. «Обычный» набор примитивов имеет дело только с парами. Например, почему у нас есть curry/uncurry только функции с 2 аргументами, а не вообще? В некоторых языках тройка представлена как вложенная пара (a,(b,c)) , и там достаточно иметь дело с парами, чтобы быть общим, но Haskell использует совершенно другой тип для повышения эффективности, поэтому, я думаю, нам нужно разрешить еще несколько примитивов в нашем преобразовании без точек.

Ответ №1:

Самый простой способ — использовать liftA2 (ab) Applicative экземпляр для функций

 import Control.Applicative

-- This two functions are defined in module Data.Tuple.Extra from extra package
-- You could use lenses too, I guess
fst3 (a,_,_) = a
snd3 (_,b,_) = b

f = liftA2 (*) fst3 snd3
 

Комментарии:

1. Я думал, что с использованием базового пакета может быть какая-то магия, но это приятно. Имея extra , мы тоже могли бы сделать f = uncurry3 (const .) . (*) , но это менее элегантно.