Διαδρομές
/
Gleam
Gleam
/
Ασκήσεις
/
Κατάστημα αυτοκόλλητων
Κατάστημα αυτοκόλλητων

Κατάστημα αυτοκόλλητων

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

Εισαγωγή

Phantom Types

Τα phantom types είναι παράμετροι τύπου ενός προσαρμοσμένου τύπου που δεν χρησιμοποιούνται σε κανέναν από τους κατασκευαστές τιμών αυτού του τύπου.

Αυτό είναι λίγο αφηρημένο, οπότε ας δούμε ένα παράδειγμα:

pub type Length(unit) {
  Length(amount: Float)
}

Σε αυτό το παράδειγμα, η παράμετρος τύπου unit δεν χρησιμοποιείται στον κατασκευαστή τιμών Length, οπότε το unit είναι ένα phantom type.

Αυτή η αχρησιμοποίητη παράμετρος τύπου μπορεί να φαίνεται άχρηστη, αλλά μπορεί να χρησιμοποιηθεί για να προσθέσει περισσότερους περιορισμούς στον τρόπο που μπορούν να χρησιμοποιηθούν οι τιμές Length.

Για παράδειγμα, θα μπορούσαμε να έχουμε μια συνάρτηση double, η οποία πολλαπλασιάζει το μήκος. Λειτουργεί με μήκη οποιασδήποτε μονάδας, οπότε η παράμετρος τύπου είναι μια γενικευμένη μεταβλητή τύπου.

// This function accepts all Length values
pub fn double(length: Length(unit)) -> Length(unit) {
  Length(length.amount *. 2.0)
}

Θα μπορούσαμε επίσης να έχουμε μια συνάρτηση add_inch, η οποία λειτουργεί μόνο αν το μήκος είναι σε ίντσες.

// A unit type for inches. It is never constructed so we don't
// define any constructors for it.
pub type Inches

pub fn add_inch(length: Length(Inches)) -> Length(Inches) {
  Length(length.amount +. 1.0)
}

Η συνάρτηση add_inch δεν θα δεχτεί μήκη με οποιαδήποτε άλλη παράμετρο μονάδας· το phantom type έχει χρησιμοποιηθεί για να διασφαλίσει ότι χρησιμοποιείται μόνο η σωστή μονάδα.

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

pub fn add(a: Length(unit), b: Length(unit)) -> Length(unit) {
  Length(a.amount +. b.amount)
}
let two_meters: Length(Meters) = Length(2.0)
let two_inches: Length(Inches) = Length(2.0)

add(two_meters, two_meters)
// -> Length(4.0): Length(Meters)

add(two_meters, two_inches)
// Type error! The unit type parameters do not match.

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

Οδηγίες

Η Lucy έχει ένα ηλεκτρονικό κατάστημα με αυτοκόλλητα, όπου πουλάει χαριτωμένα αυτοκόλλητα με τις αγαπημένες γλώσσες προγραμματισμού όλων. Άνθρωποι από όλο τον κόσμο αγοράζουν τα αυτοκόλλητά της και δυσκολεύεται λίγο να τα βγάλει πέρα με όλα τα διαφορετικά νομίσματα.

Δημιούργησε ένα πρόγραμμα που μπορεί να χρησιμοποιήσει η Lucy για να υπολογίζει τιμές, έχοντας πάντα τη βεβαιότητα ότι χρησιμοποιεί το σωστό νόμισμα.

1. Όρισε τους τύπους Usd, Eur και Jpy

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

Πρόκειται να χρησιμοποιηθούν ως phantom τύποι και δεν χρειάζεται να έχουν κανέναν κατασκευαστή.

2. Όρισε τον τύπο Money.

Ο τύπος Money πρέπει να έχει ένα πεδίο Int για το ποσό των χρημάτων, μια παράμετρο phantom τύπου για το νόμισμα, και πρέπει να είναι αδιαφανής τύπος.

3. Όρισε τις συναρτήσεις dollar, euro και yen

Όρισε τις συναρτήσεις dollar, euro και yen, οι οποίες δέχονται ένα όρισμα Int και επιστρέφουν μια τιμή Money με το σωστό νόμισμα.

4. Όρισε τη συνάρτηση total

Όρισε τη συνάρτηση total, η οποία δέχεται μια λίστα με τιμές Money και επιστρέφει το συνολικό ποσό των χρημάτων στη λίστα.

total([euro(120), euro(200), euro(145)])
// -> euro(465)
Επεξεργασία μέσω GitHub Ο σύνδεσμος ανοίγει σε νέο παράθυρο ή καρτέλα
Gleam Exercism

Έτοιμος να ξεκινήσεις την άσκηση Κατάστημα αυτοκόλλητων;

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