Pagini
Workshops
Parteneri
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
sesiuni:scala:lab6 [2016/07/04 15:48] dciocirlan |
sesiuni:scala:lab6 [2016/07/04 20:07] (current) dciocirlan |
||
---|---|---|---|
Line 21: | Line 21: | ||
You can find today's contents {{:sesiuni:scala:lab6.pdf|here}}. | You can find today's contents {{:sesiuni:scala:lab6.pdf|here}}. | ||
+ | == Practice == | ||
+ | |||
+ | Let's implement some of our own monads. | ||
+ | |||
+ | - Let's write a monad equivalent with ''Option''. Let's call this ''Maybe'', as in Haskell. | ||
+ | * create a trait ''Maybe[+A]'' (remember the ''[A]'' is equivalent to Java's ''<A>'' syntax for generics and ignore the + for now) | ||
+ | * add some functional primitives as methods to ''Maybe'': | ||
+ | * the monad requirements: ''map'', ''flatMap'', ''filter'' | ||
+ | * ''zipWith'', which receives a ''Maybe[B]'' and returns a ''Maybe[(A,B)]''\\ The signature is just a tiny bit more complex:\\ <code scala>def zipWith[B](other: Maybe[B]): Maybe[(A,B)]</code> If either ''this'' or ''other'' is empty, the result will be an empty ''Maybe''. | ||
+ | * ''exists'', which receives a predicate (a function of A to Boolean) and returns true if this instance contains an element which satisfies the predicate | ||
+ | * ''orElse'', a special method for ''Maybe'', which returns this instance if it's not empty, or an alternative otherwise; the signature will be\\ <code scala>def orElse[B >: A](alternative: Maybe[B]): Maybe[B]</code> (ignore the ''>:'' for now)\\ How can you //delay// the computation of the alternative until you actually need it? (hint: call by value/call by name) | ||
+ | * add some utility methods to the ''Maybe'' trait: | ||
+ | * ''isEmpty'' | ||
+ | * ''toList'' | ||
+ | * ''size'' | ||
+ | * create two case subclasses: ''Just[A]'' and ''Empty'' and implement the methods | ||
+ | * what is ''Empty'', actually? a case class? a case object? | ||
+ | * methods should be quick to write and probably take two lines of code, at most | ||
+ | - An equivalent to Scala's ''Try'' monad, call this ''Attempt[A]''. | ||
+ | * as before, create a trait ''Attempt[A]'' and two case subclasses, ''Success[A]'' and ''Fail'' | ||
+ | * ''Success'' has a member of type ''A'', Fail has a member of type ''Throwable'' | ||
+ | * add some functional primitives to your ''Attempt'' and implement them in the subclasses: | ||
+ | * ''map'', ''flatMap'', ''filter'' | ||
+ | * ''zipWith'' | ||
+ | * ''exists'' | ||
+ | * ''isEmpty'', ''toList'', ''size'' | ||
+ | * a special method - ''recoverWith''; the method returns an alternative ''Attempt'' computation if this one fails | ||
+ | - Talk about the Future[T] (pun intended) if you finish early! |