File tree Expand file tree Collapse file tree 2 files changed +62
-0
lines changed Expand file tree Collapse file tree 2 files changed +62
-0
lines changed Original file line number Diff line number Diff line change
1
+ package maybe
2
+
3
+ import scala .language .higherKinds
4
+
5
+ // Functor typeclass with existential F type
6
+ trait Functor [F [_]] {
7
+ def fmap [A , B ](fa : F [A ])(f : A => B ): F [B ]
8
+ }
9
+
10
+ object Functor {
11
+ // Summons functor instance if it is in scope
12
+ def apply [F [_]](implicit f : Functor [F ]): Functor [F ] = f
13
+ }
14
+
15
+ // Maybe typeclass that represents optional value. Value type is covariant
16
+ sealed trait Maybe [+ T ]
17
+ // Maybe child that holds value. Value type is covariant
18
+ case class Just [+ T ](value : T ) extends Maybe [T ]
19
+ // Maybe child that represents nothing
20
+ case object None extends Maybe [Nothing ]
21
+
22
+ object Maybe {
23
+ // Just factory method
24
+ def just [T ](value : T ): Maybe [T ] = Just (value)
25
+
26
+ // None factory method
27
+ def none [T ]: Maybe [T ] = None
28
+
29
+ // Functor implementation for Maybe
30
+ implicit val maybeFunctor : Functor [Maybe ] = new Functor [Maybe ] {
31
+ override def fmap [A , B ](fa : Maybe [A ])(f : A => B ): Maybe [B ] = fa match {
32
+ case Just (v) => Just (f(v))
33
+ case None => None
34
+ }
35
+ }
36
+ }
37
+
38
+ object Main extends App {
39
+ println(Functor [Maybe ].fmap(None )((a : Int ) => a + 2 ))
40
+ // prints None
41
+ println(Functor [Maybe ].fmap(Just (" 2" ))(_.toInt))
42
+ // prints Just(2)
43
+ }
Original file line number Diff line number Diff line change
1
+ package maybe
2
+
3
+ import scala .language .higherKinds
4
+
5
+ object FunctorSyntax {
6
+ // Implicit Functor operations class
7
+ implicit class FunctorOps [F [_], A ](val obj : F [A ]) extends AnyVal {
8
+ def fmap [B ](f : A => B )(implicit functor : Functor [F ]): F [B ] =
9
+ functor.fmap(obj)(f)
10
+ }
11
+ }
12
+
13
+ object Maybe2 extends App {
14
+ import Maybe ._
15
+ import FunctorSyntax ._
16
+
17
+ print(just(" 2" ).fmap(_.toDouble).fmap(a => a + 3 ))
18
+ // prints Just(5.0)
19
+ }
You can’t perform that action at this time.
0 commit comments