Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
pp:class [2021/04/10 16:18]
lfa
pp:class [2021/04/11 22:15] (current)
lfa
Line 1: Line 1:
 ====== 6. Classes in Haskell ====== ====== 6. Classes in Haskell ======
 +
 +=== Default Classes ===
 +
 +Today you can use the provided {{:​pp:​lab6_skel.zip|}}.
  
 Last time we've learned how to define our new data types in Haskell. The simpler ones were ''​Ordering''​ (some "​constants"​),​ ''​Point Float Float'',​ and ''​Student String String [Float]''​. Last time we've learned how to define our new data types in Haskell. The simpler ones were ''​Ordering''​ (some "​constants"​),​ ''​Point Float Float'',​ and ''​Student String String [Float]''​.
-We've seen that we can define recursively monomorphic or polymorphic types, like ''​List a''​ and ''​BTree a''​.+We've seen that we can define ​//recursively// //monomorphic// or //polymorphic// types, like ''​List a''​ and ''​BTree a''​.
  
-Today we will use the following data:+Today we will use the following data types:
 <code haskell> <code haskell>
 data List a = Null | Cons a (List a) data List a = Null | Cons a (List a)
Line 22: Line 26:
  
 Now let's check one more interesting concept, Haskell'​s class system. Now let's check one more interesting concept, Haskell'​s class system.
-If //data// can be considered the //class// from Java, then ''​class''​ could be considered the //​interface//​ from Java. 
  
 If you're defining a new //data Point//, you probably encountered some problems trying to print it in GHCI. If you're defining a new //data Point//, you probably encountered some problems trying to print it in GHCI.
Line 33: Line 36:
    show :: a -> String    show :: a -> String
 </​code>​ </​code>​
-Here ''​a''​ is a **data**. More precisely, to be able to print any data from Haskell, then it must implement the //show// function. That's why we can consider it an //​interface//​.+Here ''​a''​ is a **data ​type**. More precisely, to be able to print any data type from Haskell, then it must implement the //show// function. That's why we can consider it an //​interface//​.
  
 Providing our show will be done by enrolling our type in the already existing class Show. Here you have a simple example, in the lab skel you'll see a more complex show, //just for flexing//. Providing our show will be done by enrolling our type in the already existing class Show. Here you have a simple example, in the lab skel you'll see a more complex show, //just for flexing//.
Line 44: Line 47:
  
 1. Add List and Student to the Show class. You can print them however you want. If you aren't inspired today, you can use the following: 1. Add List and Student to the Show class. You can print them however you want. If you aren't inspired today, you can use the following:
-    ​* The lists can be the default style -> //​[3,​4,​1,​2,​]//​. +   * The lists can be the default style -> //​[3,​4,​1,​2,​]//​ 
-    * The student can be something like -> //​Studentul:​ ANDREI Alex-Bogdan = [8.5,​6.0,​8.7]//​+   ​* The student can be something like -> //​Studentul:​ ANDREI Alex-Bogdan = [8.5,​6.0,​8.7]//​
  
 2. The default ''​==''​ that we get from //deriving Eq// will check if 2 objects are identical. For our data, you'll have to provide a custom '​=='​ such that: 2. The default ''​==''​ that we get from //deriving Eq// will check if 2 objects are identical. For our data, you'll have to provide a custom '​=='​ such that:
     * list1 == list2 = True if both trees have the same elements, but in any order     * list1 == list2 = True if both trees have the same elements, but in any order
     * tree1 == tree2 = True if both trees have the same elements, but in any order     * tree1 == tree2 = True if both trees have the same elements, but in any order
-    * stud1 == stud2 = True if both students have the same average on their grades+    * stud1 == stud2 = True if both students have the same average on their grades, same last_names and same first_names
  
  
Line 60: Line 63:
  
  
-4. Let's sort students now. Add the student to the ''​Ord''​ class and provide implementations for ''<''​. The criteria will be their grades average, maximum grade, last_name, and first_name alphabetical.+4. Let's sort students now. Add the student to the ''​Ord''​ class and provide implementations for ''<''​. The criteria will be their grades average, maximum grade, last_name, and first_name alphabetical. We will sort them by rankings. //stud1 < stud2// if //stud1// is better than //stud2// by the above criteria.
  
 +=== Custom Classes ===
 +
 +What if we need to create our own classes? For a quick example, we would like a class that tells us if a data type is Empty or not. We will call this class ''​IsVoid''​ and all types enrolled in this class must implement the ''​isVoid''​ method.
 +<code haskell>
 +class IsVoid a where
 +  isVoid :: a -> Bool
 +
 +instance IsVoid Bool where
 +  isVoid False = True
 +  isVoid True  = False
 +
 +instance IsVoid (BTree a) where
 +  isVoid Void = True
 +  isVoid _    = False
 +
 +instance IsVoid [a] where
 +  isVoid [] = True
 +  isVoid _  = False
 +</​code>​
 +As you can see, now we can add our data types in the new class, but also Haskell'​s types. The only requirement is that the enrolled type must implement our method.
 +
 +5. Create a class ''​Contains b a''​ that will require a ''​contains :: b -> a -> Bool''​ method which will return True if ''​a''​ is in ''​b''​. Add ''​[a]'',​ ''​List a''​ and ''​BTree a''​ to this class.
 +<note tip>Do we need any additional restrictions for a or b? You can still add restrictions:​
 +<code haskell>
 +   class (SomeClass a) => Contains b a where ...
 +</​code></​note>​
  
 +6. Create the ''​class Size a''​ which will require the methods ''​size''​ and ''​uniqueSize''​. Add ''​[a]'',​ ''​List a''​ and ''​BTree a''​ to this class.
 +     - //size// = the numbers of elements in **a**
 +     - //​uniqueSize//​ = the number of uniqueElements in **a**