2015-05-11 1 views
14

Questo codice verifica se la password data è valida secondo i vincoli nei requisiti

import Data.Char 

strong :: String -> Bool 
strong password = all ($ password) requirements 
    where requirements = [minLength 15, any isUpper, any isLower, any isDigit] 
     minLength n str = n <= length str 
+10

Ti aiuta se ti dico che '$ password' è lo stesso di' (\ f -> f password) '? Forse puoi lavorare fuori da lì. –

+0

@JoachimBreitner è una bella scorciatoia! – dsign

risposta

15
all ($ password) requirements 
    where requirements = [minLength 15, any isUpper, any isLower, any isDigit] 

Per definizione del all, quanto sopra è equivalente a

($ password) (minLength 15) && 
($ password) (any isUpper) && 
($ password) (any isLower) && 
($ password) (any isDigit) 

Ora, in Haskell un la cosiddetta sezione(+-*/ x) sta per (\y -> y +-*/ x), qualunque sia l'operatore +-*/ (che è $, nel tuo caso). Così, si ottiene

(minLength 15 $ password) && 
(any isUpper $ password) && 
(any isLower $ password) && 
(any isDigit $ password) 

Infine, l'operatore $ è definito così: f $ x = f x, cioè esso è l'operatore applicazione funzione. Semplifichiamo ulteriormente il codice di cui sopra come:

minLength 15 password && 
any isUpper password && 
any isLower password && 
any isDigit password 
+0

A + grazie per la bella spiegazione, chi. – naomik

6

$ mezzi "Funzione di applicazione".

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

$ può essere utilizzato per fornire un parametro di una funzione. In questo caso lo si utilizza per applicare "password" a ciascuna funzione i "requisiti" hanno e hanno tipo di:

-- because $ is infix, left and right param are the 1st and 2nd respectively 
-- partial apply with the right param will still need the left one (a->b) 
:t ($ "a")  
($ "a") :: ([Char] -> b) -> b --where "b" is a bool in this case 

sembra familiare?

:t (\f -> f "a") 
(\f -> f "a") :: ([Char] -> b) -> b 

$ password e (\f -> f password) hanno lo stesso tipo e comportamento: prendere una funzione e applicare sopra a.

Quando si deve applicare una funzione su un elenco, basta mettere la funzione da sola. Ma in questo caso è necessario applicare le funzioni da un elenco a "password". Se si omette lo $, ad esempio, tenterà di eseguire "password (any isLower)", che non ha alcun senso.

Ma è possibile farlo utilizzando un lambda come all (\f -> f password) ... per applicare ciascuna funzione a password oppure è possibile farlo con $.

+0

Grazie !! Fatto. Ottima spiegazione. – bunny9131

+0

@ bunny9131 puoi accettare la mia risposta come accettata? o l'altro? –