La funzione a -> b -> (a -> b) più breve in Haskell


19

Ho ricevuto la seguente domanda durante un test:

Scrivi una funzione fcon il seguente tipo a -> b -> (a -> b). ae bnon dovrebbe essere vincolato in alcun senso, più breve è il codice, meglio è.

Mi è venuta in mente f a b = \x -> snd ([a,x],b). Riesci a trovare qualcosa di più piccolo?

Attualmente il vincitore è: f _=(.f).const


Se è consentito un tipo più generale: f = const const.
Hammar,

@hammar: o f _ b _ = b, ma, data la soluzione nella domanda, sospetto che non sia permesso un tipo più generale .
Tikhon Jelvis,

6
Se è consentito un tipo più generale, perché no f = id?
Tom Ellis,

7
In effetti, se è consentito un tipo più generale, allora f = fè una soluzione, quindi immagino che le condizioni sul tipo siano molto importanti!
Tom Ellis,

2
Non è consentito un tipo più generale, i tuoi presupposti erano corretti.
Radu Stoenescu,

Risposte:


11

Il tuo esempio può essere ridotto eliminando la funzione anonima sul lato destro:

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

Questo funziona perché il tipo a -> b -> a -> bè equivalente a a -> b -> (a -> b)in Haskell.


4
Modifica leggermente più breve:f a b x = snd (f x,b)
Ed'ka,

5

La funzione f _=(.f).constè in realtà di un tipo più generale di f :: a -> b -> (a -> b), vale a dire f :: a -> b -> (c -> b). Se non viene fornita alcuna firma del tipo, il sistema di inferenza del tipo ne deduce un tipo f :: a -> b -> (a -> b), ma se si include la firma del tipo f :: a -> b -> (c -> b)con la stessa identica definizione, Haskell la compilerà senza problemi e riporterà tipi coerenti per le applicazioni parziali di f. C'è probabilmente qualche motivo profondo per cui il sistema di inferenza del tipo è più rigoroso del sistema di controllo del tipo in questo caso, ma non capisco abbastanza teoria delle categorie per trovare un motivo sul perché questo dovrebbe essere il caso. Se non sei convinto, puoi provarlo tu stesso.


potrebbe essere come nel caso di f a b = f a a. si considera di tipo a -> a -> bsebbene sia conforme al tipo a -> b -> c. è perché se fnon gli viene dato un tipo, può usarsi solo monomorficamente.
orgoglioso haskeller il

non penso che questo dovrebbe importare però
orgoglioso haskeller il

4

Dato ScopedTypeVariables, ho pensato a questo:

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

Se riduci sia la mia funzione che la tua, la mia è più corta:

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

Naturalmente, probabilmente non ti è permesso fare affidamento su ScopedTypeVariables: P.


3
Questo non è breve come f _=(.f).const(a causa di Sassa NF ). Anche questo non ha bisogno ScopedTypeVariables.
cessò di girare in senso antiorario il

Hmm, inizialmente pensavo che questo avrebbe richiesto che il primo e il terzo argomento fossero liste ...
Chris Taylor,

@ChrisTaylor: Troppo OCaml nella mente? :)
Tikhon Jelvis,

Ah, deve essere! ;)
Chris Taylor,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.