Η αντιστοίχιση προτύπων επιτρέπει εκφραστικό κώδικα διακλάδωσης και η αποδόμηση προσφέρει κομψή δέσμευση τιμών σε μεταβλητές.
Η αντιστοίχιση προτύπων μπορεί να δεσμεύσει τιμές σε μεταβλητές ή να τις αγνοήσει με το μπαλαντέρ _, χρησιμοποιώντας την εντολή case.
type Entity = Alien | Stranger (Maybe String) | Friend { name: String }
hello : Entity -> String
hello entity =
case entity of
-- Custom type variant
Alien -> "Hello, you are not from around here are you?"
-- Binding to a litteral value nested in Stranger
Stranger (Just nametag) -> "Hello, erm... " ++ nametag ++ "."
-- Discarding Friend's data
Friend _ -> "Hi!"
-- All other cases
_ -> "Hello stranger!"
Η αποδόμηση μπορεί να δεσμεύσει τιμές σε δεσμεύσεις let, σε ορίσματα συνάρτησης και φυσικά σε εκφράσεις case, όποτε τα δεδομένα έχουν μόνο μία δυνατή μορφή.
pairSum : ( Int, Int ) -> Int
pairSum pair =
-- Destructuring of a pair in a 'let' binding
let ( x, y ) = pair
in x + y
-- Destructuring in the function argument
pairSum : ( Int, Int ) -> Int
pairSum ( x, y ) = x + y
-- Custom type containing a single variant
type Container = Box String
-- Destructuring in the function argument
unbox : Container -> String
unbox (Box str) = str
-- Destructuring combined with pattern matching
unboxMaybe : Maybe Container -> Maybe String
unboxMaybe maybeContainer =
case maybeContainer of
Nothing -> Nothing
Just (Box "42") -> Just "The answer to the universe!"
Just (Box str) -> Just str
Η αποδόμηση μπορεί επίσης να χρησιμοποιηθεί για καταγραφές, ή με τη as λέξη-κλειδί.
type alias Circle =
{ radius : Float
, center : ( Float, Float )
}
perimeter : Circle -> Float
perimeter { radius } =
2 * pi * radius
left : Circle -> Float
left { radius, center } =
-- the pair center cannot be pattern matched directly in the function argument
-- so we do it in a 'let' statement
let ( x, _ ) = center
in x - radius
-- using the 'as' keyword to bind both the fields and the whole record
smaller : Float -> Circle -> Circle
smaller reduction ({ radius } as circle) =
if reduction < radius then
{ circle | radius = radius - reduction }
else
circle
Αποτελείς μέρος της υποστήριξης πληροφορικής και θέλεις να βελτιώσεις το σύστημα δελτίων ώστε να είναι πιο αποδοτικό και να παρέχει στατιστικά στη διευθύντριά σου.
Ένα δελτίο έχει μια κατάσταση (new, in progress...), έναν δημιουργό (που ταυτοποιείται από ένα όνομα χρήστη και ένα αναγνωριστικό υπαλλήλου), μπορεί να ανατεθεί σε έναν υπάλληλο πληροφορικής και περιέχει ένα ιστορικό σχολίων.
Ακολουθούν τέσσερις εργασίες που θα βελτιώσουν το τρέχον σύστημα δελτίων σου.
Τα κενά σχόλια γεμίζουν άσκοπα τη διεπαφή και δεν προσφέρουν καμία πληροφορία, οπότε θέλεις να τα φιλτράρεις.
Όρισε μια βοηθητική συνάρτηση emptyComment που παίρνει ένα ζεύγος χρήστη/σχολίου και επιστρέφει True για τα κενά σχόλια.
Χρησιμοποίησε αποδόμηση για να εξαγάγεις τον χρήστη και το σχόλιο απευθείας στο όρισμα της συνάρτησης. Αγνόησε τον χρήστη, αφού δεν χρειάζεσαι αυτή την πληροφορία.
emptyComment ( User "Alice", "" )
-- => True
Η διευθύντριά σου θέλει να έχει στατιστικά για τη συμμετοχή των χρηστών στη διαδικασία των δελτίων. Σου ζητάει να ελέγξεις πόσα σχόλια προσθέτει ο δημιουργός του δελτίου.
Όρισε τη numberOfCreatorComments που παίρνει ένα δελτίο και επιστρέφει τον αριθμό των σχολίων που πρόσθεσε ο δημιουργός του δελτίου.
Χρησιμοποίησε αποδόμηση στο όρισμα της συνάρτησης για να εξαγάγεις την καταγραφή από τον τύπο Ticket, ταυτόχρονα με τα πεδία που χρειάζεσαι από την καταγραφή.
Έπειτα, αποδόμησε το createdBy σε έναν δεσμό let (έστω) ώστε να μπορείς να μετρήσεις τα σχετικά σχόλια.
Χρησιμοποίησε συναρτήσεις της List για τη μέτρηση και αποδόμηση στο όρισμα μιας ανώνυμης συνάρτησης για να ξεχωρίσεις το ζεύγος χρήστη/σχολίου.
numberOfCreatorComments
numberOfCreatorComments
(Ticket
{ status = Closed
, createdBy = ( User "Chiaki", 1 )
, assignedTo = Nothing
, comments = [ ( User "Chiaki", "Never mind, fixed it." ) ]
}
)
-- => 1
Κάποια δελτία πρέπει να κλιμακώνονται στους Alice, Bob ή Charlie από την Dev Team. Είναι σημαντικό να τα παρακολουθείς για να βεβαιώνεσαι ότι προχωρούν.
Όρισε μια βοηθητική συνάρτηση assignedToDevTeam που ελέγχει αν ένα δελτίο έχει ανατεθεί σε ένα από τα μέλη της Dev Team.
Χρησιμοποίησε αποδόμηση στο όρισμα της συνάρτησης για να εξαγάγεις την καταγραφή από τον τύπο Ticket καθώς και το πεδίο που χρειάζεσαι.
Έπειτα, χρησιμοποίησε μία μόνο εντολή case για να ελέγξεις αν το δελτίο έχει ανατεθεί στους Alice, Bob ή Charlie, με αναδρομική αντιστοίχιση προτύπων για να εξαγάγεις τα ονόματα χρηστών τους και αντιστοίχιση προτύπων με κυριολεκτικές τιμές για να τα αντιστοιχίσεις.
assignedToDevTeam
(Ticket
{ status = InProgress
, createdBy = ( User "Bill", 2 )
, assignedTo = Just (User "Alice")
, comments = [ ( User "Bill", "What's an 'undefined'?" ) ]
}
)
-- => True
Μερικές φορές ένα σωρό δελτία πρέπει να ανατεθούν ξανά σε άλλους υπαλλήλους πληροφορικής.
Όρισε μια συνάρτηση assignTicketTo για να σε βοηθήσει σε αυτό. Η συνάρτηση δέχεται δύο ορίσματα: έναν χρήστη στον οποίο θα ανατεθεί το δελτίο και ένα δελτίο.
Αν η κατάσταση του δελτίου είναι New, ανάθεσέ το στον νέο χρήστη και άλλαξε την κατάσταση σε InProgress.
Για τις άλλες καταστάσεις, απλώς ανάθεσε ξανά το δελτίο στους νέους χρήστες, εκτός από τα δελτία με κατάσταση Archived, τα οποία δεν πρέπει να τροποποιηθούν καθόλου.
Χρησιμοποίησε αποδόμηση στο όρισμα της συνάρτησης για να εξαγάγεις την καταγραφή από τον τύπο Ticket καθώς και το πεδίο που χρειάζεσαι, και χρησιμοποίησε επίσης τη λέξη-κλειδί as για να συλλάβεις ολόκληρη την καταγραφή όπως είναι.
Χρησιμοποίησε μία μόνο εντολή case για να αντιστοιχίσεις την κατάσταση με πρότυπα και να επιστρέψεις το κατάλληλο δελτίο, φτιαγμένο από την τροποποίηση της αρχικής καταγραφής που συνέλαβες με τη λέξη-κλειδί as.
assignTicketTo (User "Danny")
(Ticket
{ status = New
, createdBy = ( User "Jesse", 3 )
, assignedTo = Just (User "Alice")
, comments = [ ( User "Jesse", "I've been waiting for 6 months!!" ) ]
}
)
-- => Ticket
-- { status = InProgress
-- , createdBy = ( User "Jesse", 3 )
-- , assignedTo = Just (User "Danny")
-- , comments = [ ( User "Jesse", "I've been waiting for 6 months!!" ) ]
-- }
Γράψου στο Exercism για να μάθεις και να κατακτήσεις Elm με 28 έννοιες110 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.