Haskell Language
Operatori Infix
Ricerca…
Osservazioni
La maggior parte delle funzioni Haskell vengono chiamate con il nome della funzione seguito da argomenti (notazione prefisso). Per le funzioni che accettano due argomenti come (+), a volte ha senso fornire un argomento prima e dopo la funzione (infisso).
Preludio
Logico
&&
è logico AND, ||
è logico OR.
==
è l'uguaglianza, /=
non-uguaglianza, <
/ <=
minore e >
/ >=
operatori maggiori.
Operatori aritmetici
Gli operatori numerici +
, -
e /
comportano in gran parte come ci si aspetterebbe. (La divisione funziona solo su numeri frazionari per evitare problemi di arrotondamento - la divisione intera deve essere eseguita con quot
o div
). Più inusuali sono i tre operatori di exponentiation di Haskell:
^
prende una base di qualsiasi tipo di numero con un potere integrale non negativo. Funziona semplicemente con la moltiplicazione ( veloce ) iterata. Per esempio4^5 ≡ (4*4)*(4*4)*4
^^
fa lo stesso nel caso positivo, ma funziona anche per gli esponenti negativi. Per esempio3^^(-2) ≡ 1 / (2*2)
A differenza di
^
, questo richiede un tipo di base frazionale (cioè4^^5 :: Int
non funzionerà, solo4^5 :: Int
o4^^5 :: Rational
).**
implementa l'esponenziazione numero reale. Questo funziona per argomenti molto generali, ma è più costoso rispetto a^
o^^
e generalmente incorre in piccoli errori in virgola mobile.2**pi ≡ exp (pi * log 2)
elenchi
Esistono due operatori di concatenazione:
:
(pronuncia cons ) anteporre un singolo argomento prima di una lista. Questo operatore è in realtà un costruttore e può quindi essere utilizzato anche per associare la stringa ("inverse construct") a un elenco.++
concatena intere liste.[1,2] ++ [3,4] ≡ 1 : 2 : [3,4] ≡ 1 : [2,3,4] ≡ [1,2,3,4]
!!
è un operatore di indicizzazione.
[0, 10, 20, 30, 40] !! 3 ≡ 30
Si noti che gli elenchi di indicizzazione sono inefficienti (complessità O ( n ) invece di O (1) per gli array o O (log n ) per le mappe ); In Haskell è generalmente preferito decostruire le liste piegando la corrispondenza del modello anziché l'indicizzazione.
Controllo del flusso
$
è un operatore di applicazioni di funzione.f $ x ≡ f x ≡ f(x) -- disapproved style
Questo operatore è usato principalmente per evitare parentesi. Ha anche una versione rigorosa
$!
, che forza l'argomento da valutare prima di applicare la funzione..
compone le funzioni.(f . g) x ≡ f (g x) ≡ f $ g x
>>
sequenze azioni monadiche. Ad esempiowriteFile "foo.txt" "bla" >> putStrLn "Done."
scriverà prima su un file, quindi stamperà un messaggio sullo schermo.>>=
fa lo stesso, accettando anche un argomento da passare dalla prima azione alla seguente.readLn >>= \x -> print (x^2)
attenderà che l'utente inserisca un numero, quindireadLn >>= \x -> print (x^2)
il quadrato di quel numero sullo schermo.
Operatori personalizzati
In Haskell, puoi definire qualsiasi operatore di infissi che ti piace. Ad esempio, potrei definire l'operatore elenco-inviluppo come
(>+<) :: [a] -> [a] -> [a]
env >+< l = env ++ l ++ env
GHCi> "**">+<"emphasis"
"**emphasis**"
Si dovrebbe sempre dare a tali operatori una dichiarazione di fissità , come
infixr 5 >+<
(che significherebbe >+<
binds strettamente come ++
e :
do).
Trovare informazioni sugli operatori infissi
Poiché gli hasnee sono così comuni in Haskell, dovrai regolarmente controllare la loro firma, ecc. Fortunatamente, questo è semplice come per qualsiasi altra funzione:
I motori di ricerca Haskell Hayoo e Hoogle possono essere utilizzati per operatori infissi, come per qualsiasi altra cosa definita in alcune librerie.
In GHCi o IHaskell, è possibile utilizzare la
:i
e:t
(i nfo e t ipo) le direttive per imparare le proprietà di base di un operatore. Per esempio,Prelude> :i + class Num a where (+) :: a -> a -> a ... -- Defined in ‘GHC.Num’ infixl 6 + Prelude> :i ^^ (^^) :: (Fractional a, Integral b) => a -> b -> a -- Defined in ‘GHC.Real’ infixr 8 ^^
Questo mi dice che
^^
lega più strettamente di+
, entrambi prendono tipi numerici come loro elementi, ma^^
richiede che l'esponente sia integrale e la base sia frazionaria.
Meno dettagliato:t
richiede l'operatore tra parentesi, comePrelude> :t (==) (==) :: Eq a => a -> a -> Bool