11

Ho difficoltà a capire come funziona l'applicazione di funzione con il curring in haskell. Se ho seguente funzione:Applicazione per operatore dollaro Haskell

($) :: (a -> b) -> a -> b 

comprendo che applicare parzialmente questa funzione è necessario fornire (a -> b) funzione ($ s' primo argomento).

Perché allora è possibile applicare prima un valore (cioè argomenti inversi)?

($ 0) :: Num a => (a -> b) -> b 

Cosa mi manca qui?

risposta

13

($) è un operatore. In Haskell, qualsiasi operatore può essere scritto in un sinistra-sezione (come (x $)) o un diritto sezione (come ($ x)):

(x $) = (\y -> x $ y) = ($) x 
($ x) = (\y -> y $ x) = flip ($) x 

Si noti che l'unica eccezione a questa regola è (-), al fine di scrivere comodamente i numeri negativi:

\x -> (x-) :: Num a => a -> a -> a -- equivalent to \x -> (-) x 
\x -> (-x) :: Num a => a -> a  -- equivalent to \x -> negate x 

Nel caso in cui si desidera scrivere concisamente (\y -> y - x), è possibile utilizzare subtract:

\x -> subtract x :: Num a => a -> a -> a -- equivalent to \x -> flip (-) x 
+0

Grazie, questo spiega perché funziona in questo modo. Queste definizioni sono caratteristiche linguistiche o possono essere trovate da qualche parte nelle fonti? – Rumca

+2

@Rumca Non proprio nella fonte, (x $) e ($ x) sono sezioni e una loro descrizione può essere trovata nel [rapporto haskell del 2010] (http://www.haskell.org/onlinereport/haskell2010/) nella sezione [sezioni] (http://www.haskell.org/onlinereport/haskell2010/haskellch3.html#x8-300003.5). – Davorak

+0

La lingua è descritta nel [Rapporto Haskell 2010] (http://www.haskell.org/onlinereport/haskell2010/). –

4

($ 0) ≡ ≡ (\x -> x $ 0)(\x -> ($) x 0)

Se ($) :: (a -> b) -> a -> b) e abbiamo applicato secondo argomento come (\x -> ($) x 0) abbiamo :: Num a => (a -> b) -> b

2

Si sta confondendo la notazione infissa di un operatore con una funzione.

> :t (($) (+1)) 
(($) (+1)) :: Num b => b -> b 

Ecco alcune forme di espressione con $, per una migliore comprensione:

un $ b => ($) ab

($ b) => Flip ($) b => (\ ba -> ($) ab) b => \ a -> ($) ab

(a $) => ($) a => \ b -> ($) ab

+0

-1 Anche se qualcuno che comprende con fermezza di cosa tratta questa domanda e qual è il ragionamento, trovo questa risposta incomprensibile. In che modo qualcuno che non conosce Haskell dovrebbe benissimo dare un senso a questo? Nessuna spiegazione di quale sia la differenza tra operatori e funzioni. '$ b => flip ($) b => \ a -> ($) a b' non è nemmeno una sintassi valida. (Modifica: Va bene sarà -1 se avessi un piccolo rappresentante in più.) –

1

Nota anche che nella sintassi Haskell, i nomi alfanumerici si distinguono dai nomi di punteggiatura.

Una funzione alfanumerica foo1 a b è prefisso per impostazione predefinita e diventa infisso se si aggiungono reticoli: a `foo` b.

Una funzione punteggiatura nome come $ o <*> è infisso di default, e diventa il prefisso se si aggiunge parentesi ($) o (<*>). Questo è solo lo zucchero sintassi per il programmatore che conosce l'alfabeto latino; è una distinzione arbitraria ma utile tra nomi alfanumerici e nomi di punteggiatura.

Entrambi i tipi di funzioni sono solo funzioni, non hanno le regole semantiche speciali che abbiamo per "operatori" in C++ o Java. Sono solo le regole di sintassi attorno a prefisso/infisso e apici/parentesi che differiscono tra le funzioni con nomi di punteggiatura e le funzioni con nome alfanumerico.

Problemi correlati