Podczas testu dostałem następujące pytanie:
Napisz funkcję
f
o następującym typiea -> b -> (a -> b)
.a
ib
nie powinien być w żaden sposób związany, im krótszy kod, tym lepiej.
Wymyśliłem f a b = \x -> snd ([a,x],b)
. Czy możesz znaleźć coś mniejszego?
Obecnie zwycięzcą jest: f _=(.f).const
code-golf
functional-programming
haskell
Radu Stoenescu
źródło
źródło
f = const const
.f _ b _ = b
, ale, biorąc pod uwagę rozwiązanie w kwestii, podejrzewam bardziej ogólny typ jest nie dozwolone.f = id
?f = f
to rozwiązanie, więc myślę, że warunki na typie są bardzo ważne!Odpowiedzi:
Twój przykład można zmniejszyć, pozbywając się anonimowej funkcji po prawej stronie:
Działa to, ponieważ typ
a -> b -> a -> b
jest równoważny za -> b -> (a -> b)
Haskell.źródło
f a b x = snd (f x,b)
Ta funkcja
f _=(.f).const
jest w rzeczywistości bardziej ogólna niżf :: a -> b -> (a -> b)
mianowicief :: a -> b -> (c -> b)
. Jeśli nie zostanie podany podpis typu, system wnioskowania o typ wyszuka typf :: a -> b -> (a -> b)
, ale jeśli podasz podpis typuf :: a -> b -> (c -> b)
z dokładnie taką samą definicją, Haskell skompiluje go bez problemu i zgłosi spójne typy dla częściowych zastosowań f. Prawdopodobnie istnieje jakiś głęboki powód, dla którego system wnioskowania typu jest bardziej rygorystyczny niż system sprawdzania typu w tym przypadku, ale nie rozumiem wystarczającej teorii kategorii, aby wymyślić powód, dla którego tak powinno być. Jeśli nie jesteś przekonany, możesz spróbować samemu.źródło
f a b = f a a
. wydaje się być typem,a -> a -> b
chociaż jest zgodny z typema -> b -> c
. Dzieje się tak, ponieważ jeślif
nie zostanie podany typ, może używać się tylko monomorficznie.Dany
ScopedTypeVariables
, wpadłem na to:Jeśli zmniejszysz zarówno moją funkcję, jak i twoją, moja będzie o włos krótsza:
Oczywiście prawdopodobnie nie możesz polegać na
ScopedTypeVariables
: P.źródło
f _=(.f).const
(z powodu Sassa NF ). Co też nie potrzebujeScopedTypeVariables
.