Кратчайшая функция 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)
Ed'ka

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( из-за Sassa NF ). Что тоже не нужно ScopedTypeVariables.
перестал поворачивать против часовой стрелки

Хм, я изначально думал, что это потребует, чтобы первый и третий аргументы были списками ...
Крис Тейлор

@ChrisTaylor: Слишком много OCaml на уме? :)
Тихон Джелвис

Ха, должно быть! ;)
Крис Тейлор
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.