-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexam2018.scala
160 lines (112 loc) · 4.03 KB
/
exam2018.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// Name: Emil Christian Lyngeaard
// ITU email: ecly@itu.dk
package adpro.exam2018
import fpinscala.monoids.Monoid
import fpinscala.monads.Monad
import fpinscala.monads.Functor
import fpinscala.laziness.{Stream,Empty,Cons}
import fpinscala.laziness.Stream._
import fpinscala.parallelism.Par._
import scala.language.higherKinds
import adpro.data._
import adpro.data.FingerTree._
import monocle.Lens
object Q1 {
def hasKey[K,V] (l: List[(K,V)]) (k: K) :Boolean =
l exists { case (k1,v) => k1 == k }
private def f[K,V] (acc: List[(K,List[V])], el: (K,V)) :List[(K,List[V])] =
if (hasKey (acc) (el._1))
acc.map { case (k,v) => if (k==el._1) (k,el._2::v) else (k,v) }
else (el._1,List(el._2))::acc
def groupByKey[K,V] (l :List[(K,V)]) :List[(K,List[V])] = {
val acc : List[(K, List[V])] = Nil
l.foldLeft (acc) (f _)
}
// Using a car:
// def groupByKey[K,V] (l :List[(K,V)]) :List[(K,List[V])] =
// l.groupBy(_._1).map(x => (x._1, x._2.map(_._2))).toList
}
object Q2 {
def f[A,B] (results: List[Either[A,B]]) :Either[List[A],List[B]] = {
if (results.exists(_.isLeft)) {
Left(results.filter(_.isLeft).map{case Left(x) => x})
} else {
Right(results.map{case Right(x) => x})
}
}
}
object Q3 {
type T[B] = Either[String,B]
implicit val eitherStringIsMonad :Monad[T] = new Monad[T] {
def unit[A] (a: => A): T[A] = Right(a)
override def flatMap[A,B] (ma: T[A]) (f: A => T[B]) :T[B] = ma.flatMap (f)
}
implicit def eitherIsMonad[A] = {
type T[B] = Either[A,B]
def unit[A] (a: => A): T[A] = Right(a)
def flatMap[A,B] (ma: T[A]) (f: A => T[B]) :T[B] = ma.flatMap (f)
}
}
object Q4 {
// Write the answers in English below.
// A. A stream with the Fibonacci numbers.
// 1,1,2,3,5
// B. All tuples with neighboring Fibonacci numbers,
// starting with the tuple (1, 1), followed by (1, 2)...
}
object Q5 {
def parForall[A] (as: List[A]) (p: A => Boolean): Par[Boolean] = {
val bs: Par[List[Boolean]] = parMap (as) (p)
map[List[Boolean],Boolean] (bs) (bs => bs exists (!_) )
}
}
object Q6 {
def apply[F[_],A,B](fab: F[A => B])(fa: F[A]): F[B] = ???
def unit[F[_],A](a: => A): F[A] = ???
val f: (Int,Int) => Int = _ + _
def a :List[Int] = ???
// Answer below in a comment:
// f.curried = (Int) => (Int) => (Int)
//
// x is of type List[Int]
// We basically do two applys, such that f.curried first
// is applied with its first parameter, then its second, resulting
// in integers.
} // Q6
object Q7 {
def map2[A,B,C] (a :List[A], b: List[B]) (f: (A,B) => C): List[C] = ???
def map3[A,B,C,D] (a :List[A], b: List[B], c: List[C]) (f: (A,B,C) => D) :List[D] = {
val temp : List[(A,B)] = map2(a,b){case (x,y) => (x,y)}
map2(temp, c){case ((xa, xb),xc) => f(xa,xb,xc)}
}
def map3monad[A,B,C,D,M[_] <: Monad[M]] (a :M[A], b :M[B], c :M[C]) (f: (A,B,C) => D) :M[D] = {
val temp : M[(A,B)] = a.map2(a,b){case (x,y) => (x,y)}
a.map2(temp, c){case ((xa, xb),xc) => f(xa,xb,xc)}
}
}
object Q8 {
def filter[A] (t: FingerTree[A]) (p: A => Boolean): FingerTree[A] = {
val empty = adpro.data.Empty ()
reduceL[A,FingerTree[A]] { case (acc,a) => if (p(a)) acc addR a else acc} (empty, t)
}
}
object Q9 {
def eitherOption[A,B] (default: => A): Lens[Either[A,B],Option[B]] = {
def tryGet (x : Either[A,B]) : Option[B] = x match {
case Right(x) => Some(x)
case _ => None
}
Lens[Either[A,B],Option[B]] (tryGet _) (x => _ => x match {
case Some(y) => Right(y)
case None => Left(default)
})
}
// Answer the questions below:
// A. Yes - when we eg. put Some(4), it will be Some(4) when we get,
// despite being stored as Right(4)
// B. No - if we have Left("blah") as x and our Lens as l, we get:
// l.set(l.get(x))(x) == x, meaning
// l.set(None)(Left(4)) == x which is false, as it will be Left(default)
// C. Yes - since a second 'set' is independent of the first set's result,
// which is indicated from the ignored second paramenter in our Lens defintion.
} // Q9