Найкоротша a -> b -> (a -> b) функція в Haskell


19

Я отримав наступне питання на тесті:

Напишіть функцію fнаступного типу a -> b -> (a -> b). aі bне повинні бути пов'язані в жодному сенсі, чим коротший код, тим краще.

Я придумав f a b = \x -> snd ([a,x],b). Ви можете знайти щось крихітніше?

На даний момент переможець: f _=(.f).const


Якщо більш загальний тип допускається: f = const const.
гаммар

@hammar: або f _ b _ = b, але, з огляду на рішення в цьому питанні, я підозрюю , що більш загальний тип НЕ допускається.
Тихон Єлвіс

6
Якщо дозволений більш загальний тип, чому б ні f = id?
Том Елліс

7
Насправді, якщо дозволений більш загальний тип, то f = fце рішення, тому я думаю, що умови для цього типу дуже важливі!
Том Елліс

2
Більш загальний тип заборонений, ваші припущення були правильними.
Раду Стоенеску

Відповіді:


11

Ваш приклад можна зменшити, позбувшись анонімної функції праворуч:

f a b x = snd ([a,x],b)

Це працює, тому що тип a -> b -> a -> bеквівалентний a -> b -> (a -> b)Haskell.


4
Трохи коротша модифікація:f a b x = snd (f x,b)
Едька

5

Функція f _=(.f).constнасправді є більш загальним типом, ніж f :: a -> b -> (a -> b), а саме f :: a -> b -> (c -> b). Якщо не надано підпису типу, система виводу типу підводить тип f :: a -> b -> (a -> b), але якщо ви включите підпис типу f :: a -> b -> (c -> b)з точно таким же визначенням, Haskell складе його без випуску і повідомить про послідовні типи для часткових застосувань f. Напевно, є якась глибока причина, чому система виводу типу суворіша, ніж система перевірки типу в цьому випадку, але я не розумію достатньо теорії категорій, щоб придумати причину, чому саме так має бути. Якщо ви не переконані, можете просто спробувати.


можливо, як у випадку з f a b = f a a. він вважає, що він має тип, a -> a -> bхоча він відповідає типу a -> b -> c. це тому, що якщо fйому не надано тип, він може використовувати себе мономорфно.
гордий haskeller

Я не думаю, що це має мати значення
гордий haskeller

4

Враховуючи ScopedTypeVariables, я придумав таке:

f (_::a) b (_::a) = b

Якщо ви зменшите і мою функцію, і вашу, моє волосся коротше:

f(_::a)b(_::a)=b
f a b x=snd([a,x],b)

Звичайно, на вас, мабуть, не дозволяють покладатися ScopedTypeVariables: P.


3
Це не так коротко, як f _=(.f).const( завдяки Сассі Н.Ф. ). Що також не потрібно ScopedTypeVariables.
перестали повертати проти годинника,

Гм, я спочатку думав, що для цього знадобиться перший та третій аргументи у списках ...
Кріс Тейлор

@ChrisTaylor: Занадто багато OCaml на увазі? :)
Тихон Єлвіс

Га, повинно бути! ;)
Кріс Тейлор
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.