Διαδρομές
/
Elm
Elm
/
Ασκήσεις
/
Το εισιτήριό σου, παρακαλώ!
Το εισιτήριό σου, παρακαλώ!

Το εισιτήριό σου, παρακαλώ!

Άσκηση εκμάθησης

Εισαγωγή

Αντιστοίχιση προτύπων

Η αντιστοίχιση προτύπων επιτρέπει εκφραστικό κώδικα διακλάδωσης και η αποδόμηση προσφέρει κομψή δέσμευση τιμών σε μεταβλητές.

Απλή αντιστοίχιση προτύπων

Η αντιστοίχιση προτύπων μπορεί να δεσμεύσει τιμές σε μεταβλητές ή να τις αγνοήσει με το μπαλαντέρ _, χρησιμοποιώντας την εντολή 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...), έναν δημιουργό (που ταυτοποιείται από ένα όνομα χρήστη και ένα αναγνωριστικό υπαλλήλου), μπορεί να ανατεθεί σε έναν υπάλληλο πληροφορικής και περιέχει ένα ιστορικό σχολίων.

Ακολουθούν τέσσερις εργασίες που θα βελτιώσουν το τρέχον σύστημα δελτίων σου.

1. Εντόπισε τα κενά σχόλια

Τα κενά σχόλια γεμίζουν άσκοπα τη διεπαφή και δεν προσφέρουν καμία πληροφορία, οπότε θέλεις να τα φιλτράρεις.

Όρισε μια βοηθητική συνάρτηση emptyComment που παίρνει ένα ζεύγος χρήστη/σχολίου και επιστρέφει True για τα κενά σχόλια.

Χρησιμοποίησε αποδόμηση για να εξαγάγεις τον χρήστη και το σχόλιο απευθείας στο όρισμα της συνάρτησης. Αγνόησε τον χρήστη, αφού δεν χρειάζεσαι αυτή την πληροφορία.

emptyComment ( User "Alice", "" )
-- => True

2. Μέτρησε τον αριθμό των σχολίων από τον δημιουργό

Η διευθύντριά σου θέλει να έχει στατιστικά για τη συμμετοχή των χρηστών στη διαδικασία των δελτίων. Σου ζητάει να ελέγξεις πόσα σχόλια προσθέτει ο δημιουργός του δελτίου.

Όρισε τη numberOfCreatorComments που παίρνει ένα δελτίο και επιστρέφει τον αριθμό των σχολίων που πρόσθεσε ο δημιουργός του δελτίου.

Χρησιμοποίησε αποδόμηση στο όρισμα της συνάρτησης για να εξαγάγεις την καταγραφή από τον τύπο Ticket, ταυτόχρονα με τα πεδία που χρειάζεσαι από την καταγραφή. Έπειτα, αποδόμησε το createdBy σε έναν δεσμό let (έστω) ώστε να μπορείς να μετρήσεις τα σχετικά σχόλια. Χρησιμοποίησε συναρτήσεις της List για τη μέτρηση και αποδόμηση στο όρισμα μιας ανώνυμης συνάρτησης για να ξεχωρίσεις το ζεύγος χρήστη/σχολίου.

numberOfCreatorComments
numberOfCreatorComments
    (Ticket
        { status = Closed
        , createdBy = ( User "Chiaki", 1 )
        , assignedTo = Nothing
        , comments = [ ( User "Chiaki", "Never mind, fixed it." ) ]
        }
    )
-- => 1

3. Εντόπισε τα δελτία που έχουν ανατεθεί στην Dev Team

Κάποια δελτία πρέπει να κλιμακώνονται στους 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

4. Ανάθεσε δελτία σε υπαλλήλους πληροφορικής

Μερικές φορές ένα σωρό δελτία πρέπει να ανατεθούν ξανά σε άλλους υπαλλήλους πληροφορικής.

Όρισε μια συνάρτηση 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!!" ) ]
--        }
Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα
Elm Exercism

Έτοιμος να ξεκινήσεις την άσκηση Το εισιτήριό σου, παρακαλώ!;

Γράψου στο Exercism για να μάθεις και να κατακτήσεις Elm με 28 έννοιες110 ασκήσεις και πραγματική καθοδήγηση από ανθρώπους, όλα δωρεάν.