Eu recebi a seguinte pergunta em um teste:
Escreva uma função
f
com o seguinte tipoa -> b -> (a -> b)
.a
eb
não deve ser vinculado em nenhum sentido, quanto menor o código, melhor.
Eu inventei f a b = \x -> snd ([a,x],b)
. Você consegue encontrar algo menor?
Atualmente o vencedor é: f _=(.f).const
code-golf
functional-programming
haskell
Radu Stoenescu
fonte
fonte
f = const const
.f _ b _ = b
, mas, dada a solução na pergunta, suspeito que um tipo mais geral não seja permitido.f = id
?f = f
é uma solução, então acho que as condições no tipo são muito importantes!Respostas:
Seu exemplo pode ser reduzido ao se livrar da função anônima no lado direito:
Isso funciona porque o tipo
a -> b -> a -> b
é equivalentea -> b -> (a -> b)
em Haskell.fonte
f a b x = snd (f x,b)
A função
f _=(.f).const
é realmente de um tipo mais geral quef :: a -> b -> (a -> b)
, a saberf :: a -> b -> (c -> b)
. Se nenhuma assinatura de tipo for fornecida, o sistema de inferência de tipo inferirá um tipo def :: a -> b -> (a -> b)
, mas se você incluir a assinatura de tipof :: a -> b -> (c -> b)
com exatamente a mesma definição, Haskell a compilará sem problemas e relatará tipos consistentes para as aplicações parciais de f. Provavelmente, existe alguma razão profunda pela qual o sistema de inferência de tipo é mais rigoroso do que o sistema de verificação de tipo neste caso, mas não entendo a teoria de categorias suficiente para apresentar uma razão de por que esse deveria ser o caso. Se você não está convencido, pode tentar por conta própria.fonte
f a b = f a a
. infere ser do tipo,a -> a -> b
embora esteja em conformidade com o tipoa -> b -> c
. é porque, sef
não receber um tipo, ele só poderá usar-se monomorficamente.Dado
ScopedTypeVariables
, eu vim com isso:Se você reduzir minha função e a sua, a minha é mais curta:
Claro, você provavelmente não tem permissão para confiar em
ScopedTypeVariables
: P.fonte
f _=(.f).const
( devido ao Sassa NF ). O que também não precisaScopedTypeVariables
.