На тесте я получил следующий вопрос:
Напишите функцию
f
следующего типаa -> b -> (a -> b)
.a
иb
не должно быть связано ни в каком смысле, чем короче код, тем лучше.
Я придумал f a b = \x -> snd ([a,x],b)
. Можете ли вы найти что-нибудь круче?
На данный момент победителем является: f _=(.f).const
code-golf
functional-programming
haskell
Раду Стоенеску
источник
источник
f = const const
.f _ b _ = b
, но, учитывая решение вопроса, я подозреваю, что более общий тип не допускается.f = id
?f = f
это решение, поэтому я думаю, что условия для типа очень важны!Ответы:
Ваш пример можно сократить, избавившись от анонимной функции в правой части:
Это работает, потому что тип
a -> b -> a -> b
эквивалентенa -> b -> (a -> b)
в Haskell.источник
f a b x = snd (f x,b)
Функция
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
ему не дан тип, он может использовать себя только мономорфно.Учитывая
ScopedTypeVariables
, я придумал это:Если вы сократите и мою, и вашу функцию, у меня на голову короче:
Конечно, вы, вероятно, не можете положиться на
ScopedTypeVariables
: P.источник
f _=(.f).const
( из-за Sassa NF ). Что тоже не нужноScopedTypeVariables
.