How does the A turn to be Nothing in the process?
def seq2map[A](src: Seq[A]): Map[A, A] = {
def pair = for {
f <- src.headOption
s <- src.headOption
} yield (f, s)
Stream continually pair takeWhile(_ isDefined) toMap
}
error: Expression of type Map[Nothing, Nothing] doesn't conform to expected type Map[A, A]
Thank you!
I get
<console>:12: error: Cannot prove that Option[(A, A)] <:< (T, U).
Stream continually pair takeWhile(_ isDefined) toMap
^
because
scala> val src = (1 to 10).toSeq
src: scala.collection.immutable.Range = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> def pair = for {
| f <- src.headOption
| s <- src.headOption
| } yield (f, s)
pair: Option[(Int, Int)]
is not a pair, but an Option.
scala> (Stream continually pair takeWhile (_.isDefined)).flatten
res0: scala.collection.immutable.Stream[(Int, Int)] = Stream((1,1), ?)
is a stream of pairs.
Just waiting for the game to start.
Related
I'm trying to define a method ConcatToList would be able to convert some objects of type T~T or T~T~T or T~T~T~T or ...
to a List[T].
My problem comes with how I should go about defining the type of ConcatToList
def ConcatToList[T](concat: ~[T, ???]) = ...
what should I replace ??? by ?
I'll assume a representation like this:
class ~[I, L](val init: I, val last: L)
That you instantiate like this:
scala> val x: Int ~ Int ~ Int ~ Int = new ~(new ~(new ~(1, 2), 3), 4)
x: ~[~[~[Int,Int],Int],Int] = $tilde#3e6fa38a
You're not going to be able to write your ConcatToList method with a signature of the form you suggest, since there's no way to write a type constraint that describes exactly the types for which this operation is valid. Instead you can use a type class:
trait TildeToList[T] {
type Elem
def apply(t: T): List[Elem]
}
object TildeToList {
type Aux[T, E] = TildeToList[T] { type Elem = E }
implicit def baseTildeToList[E]: Aux[E ~ E, E] = new TildeToList[E ~ E] {
type Elem = E
def apply(t: E ~ E): List[E] = List(t.init, t.last)
}
implicit def recTildeToList[I, L](implicit ttl: Aux[I, L]): Aux[I ~ L, L] =
new TildeToList[I ~ L] {
type Elem = L
def apply(t: I ~ L): List[L] = ttl(t.init) :+ t.last
}
}
And then:
def tildeToList[T](t: T)(implicit ttl: TildeToList[T]): List[ttl.Elem] = ttl(t)
Which works like this:
scala> tildeToList(x)
res0: List[Int] = List(1, 2, 3, 4)
Note that what we get back is appropriately statically typed.
If you try to use it on a value that doesn't have an appropriate shape, you'll get a compile-time error:
scala> tildeToList(new ~('a, "a"))
<console>:16: error: could not find implicit value for parameter ttl: TildeToList[~[Symbol,String]]
tildeToList(new ~('a, "a"))
^
Which is presumably what you want.
The next code works for lists of mixed types:
case class ~~[T, G](l: T, r: G)
def concat[T, G](v: ~~[T, G]): List[T] = (v.l, v.r) match {
case (left, right : ~~[T, _]) => left :: concat(right)
case (left, right: T) => List(left, right)
}
println(concat(~~(2, 3))) // List(2, 3)
println(concat(~~(2, ~~(4, 5)))) // List(2, 4, 5)
println(concat(~~(2, ~~(4, ~~(5, 6))))) // List(2, 4, 5, 6)
println(concat(~~(2, ~~("s", 3.3)))) // List(2, s, 3.3)
// but
println(concat(~~(~~("s", 3.3), 2))) // List(~~(s, 3.3), 2)
P.S. I will leave this as an example of simple approach, but see Travis response for a better type-safer way
This is a follow-up to one of my recent previous questions:
I would like to define a zip Applicative instance for List (and probably Set and Map). For example:
val xs: List[Int] = List(1, 2, 3)
val fs: List[Int => Int] = List(f1, f2, f3)
val ys: List[Int] = xs <*> fs // expected to be List(f1(1), f2(2), f3(3))
So I defined a ZipList and its Applicative:
case class ZipList[A](val list: List[A])
implicit val zipListApplicative = new Applicative[ZipList] {
def point[A](a: => A): ZipList[A] = ZipList(List(a))
def ap[A, B](za: => ZipList[A])(zf: => ZipList[A => B]): ZipList[B] = {
val bs = (za.list zip zf.list) map {case (a, f) => f(a)}
ZipList(bs)
}
}
and can use it as follows:
scala> val xs: List[Int] = List(1, 2, 3)
xs: List[Int] = List(1, 2, 3)
scala> val fs: List[Int => Int] = List(_ + 2, _ + 2, _ +1)
fs: List[Int => Int] = List(<function1>, <function1>, <function1>)
scala> ZipList(xs) <*> ZipList(fs)
res4: ZipList[Int] = ZipList(List(3, 4, 4))
It seems to be working but maybe I am missing something.
Does zipListApplicative comply to the applicative laws ?
Is ZipList supposed to be a stream because the point should generate an infinite stream of values ? Why ?
Applicatives should satisfy the law
point identity <*> v == v
which yours does not since
point identity List(1,2,3) == List(1)
pure a for a zip list should return an infinite stream of a which is why you need a lazy data structure.
Reading the paper on Types and Polymorphism in programming languages, i wondered is it possible to express the similar universal quantification on type members with Scala. Example from the paper:
type GenericID = ∀A.A ↦ A
Which is a type for generic identity function and the following example in their paper language Fun was correct:
value inst = fun(f: ∀a.a ↦ a) (f[Int], f[Bool])
value intId = fst(inst(id)) // return a function Int ↦ Int
Is there some way to express the similar thing in Scala?
This is not the same as type constructor type GenericId[A] = A => A, cause it's a type operation when ∀A.A ↦ A is a type for generic function
Following on from my comment above:
scala> type Gen[+_] = _ => _
defined type alias Gen
scala> def f(x: List[Int]): Gen[List[Int]] = x map (y => s"{$y!$y}")
f: (x: List[Int])Gen[List[Int]]
scala> f(List(1, 4, 9))
res0: Function1[_, Any] = List({1!1}, {4!4}, {9!9})
In other words, identity of types has not been preserved by Gen[+_] = _ => _.
Addendum
scala> type Identity[A] = A => A
defined type alias Identity
scala> def f(x: List[Int]): Identity[List[Int]] = x => x.reverse
f: (x: List[Int])List[Int] => List[Int]
scala> f(List(1, 4, 9))
res1: List[Int] => List[Int] = <function1>
scala> def g(x: List[Int]): Identity[List[Int]] = x => x map (y => s"{$y!$y}")
<console>:35: error: type mismatch;
found : List[String]
required: List[Int]
def g(x: List[Int]): Identity[List[Int]] = x => x map (y => s"{$y!$y}")
Try: type Gen[+_] = _ => _
scala> def f(x:List[Int]):Gen[List[Int]] = x.reverse
f: (x: List[Int])Gen[List[Int]]
scala> f(List(3,4))
res0: Function1[_, Any] = List(4, 3)
scala> def f(x:List[Number]):Gen[List[Number]] = x.reverse
f: (x: List[Number])Gen[List[Number]]
scala> f(List(3,4))
res1: Function1[_, Any] = List(4, 3)
What would be a functional way to zip two dictionaries in Scala?
map1 = new HashMap("A"->1,"B"->2)
map2 = new HashMap("B"->22,"D"->4) // B is the only common key
zipper(map1,map2) should give something similar to
Seq( ("A",1,0), // no A in second map, so third value is zero
("B",2,22),
("D",0,4)) // no D in first map, so second value is zero
If not functional, any other style is also appreciated
def zipper(map1: Map[String, Int], map2: Map[String, Int]) = {
for(key <- map1.keys ++ map2.keys)
yield (key, map1.getOrElse(key, 0), map2.getOrElse(key, 0))
}
scala> val map1 = scala.collection.immutable.HashMap("A" -> 1, "B" -> 2)
map1: scala.collection.immutable.HashMap[String,Int] = Map(A -> 1, B -> 2)
scala> val map2 = scala.collection.immutable.HashMap("B" -> 22, "D" -> 4)
map2: scala.collection.immutable.HashMap[String,Int] = Map(B -> 22, D -> 4)
scala> :load Zipper.scala
Loading Zipper.scala...
zipper: (map1: Map[String,Int], map2: Map[String,Int])Iterable[(String, Int, Int)]
scala> zipper(map1, map2)
res1: Iterable[(String, Int, Int)] = Set((A,1,0), (B,2,22), (D,0,4))
Note using get is probably preferable to getOrElse in this case. None is used to specify that a value does not exist instead of using 0.
As an alternative to Brian's answer, this can be used to enhance the map class by way of implicit methods:
implicit class MapUtils[K, +V](map: collection.Map[K, V]) {
def zipAllByKey[B >: V, C >: V](that: collection.Map[K, C], thisElem: B, thatElem: C): Iterable[(K, B, C)] =
for (key <- map.keys ++ that.keys)
yield (key, map.getOrElse(key, thisElem), that.getOrElse(key, thatElem))
}
The naming and API are similar to the sequence zipAll.
Im looking to extended the iterator to create a new method takeWhileInclusive, which will operate like takeWhile but include the last element.
My issue is what is best practice to extend the iterator to return a new iterator which I would like to be lazy evaluated. Coming from a C# background I normal use IEnumerable and use the yield keyword, but such an option doesn't appear to exist in Scala.
for example I could have
List(0,1,2,3,4,5,6,7).iterator.map(complex time consuming algorithm).takeWhileInclusive(_ < 6)
so in this case the takeWhileInclusive would only have resolve the predicate on the values until I get the a result greater than 6, and it will include this first result
so far I have:
object ImplicitIterator {
implicit def extendIterator(i : Iterator[Any]) = new IteratorExtension(i)
}
class IteratorExtension[T <: Any](i : Iterator[T]) {
def takeWhileInclusive(predicate:(T) => Boolean) = ?
}
You can use the span method of Iterator to do this pretty cleanly:
class IteratorExtension[A](i : Iterator[A]) {
def takeWhileInclusive(p: A => Boolean) = {
val (a, b) = i.span(p)
a ++ (if (b.hasNext) Some(b.next) else None)
}
}
object ImplicitIterator {
implicit def extendIterator[A](i : Iterator[A]) = new IteratorExtension(i)
}
import ImplicitIterator._
Now (0 until 10).toIterator.takeWhileInclusive(_ < 4).toList gives List(0, 1, 2, 3, 4), for example.
This is one case where I find the mutable solution superior:
class InclusiveIterator[A](ia: Iterator[A]) {
def takeWhileInclusive(p: A => Boolean) = {
var done = false
val p2 = (a: A) => !done && { if (!p(a)) done=true; true }
ia.takeWhile(p2)
}
}
implicit def iterator_can_include[A](ia: Iterator[A]) = new InclusiveIterator(ia)
The following requires scalaz to get fold on a tuple (A, B)
scala> implicit def Iterator_Is_TWI[A](itr: Iterator[A]) = new {
| def takeWhileIncl(p: A => Boolean)
| = itr span p fold (_ ++ _.toStream.headOption)
| }
Iterator_Is_TWI: [A](itr: Iterator[A])java.lang.Object{def takeWhileIncl(p: A => Boolean): Iterator[A]}
Here it is at work:
scala> List(1, 2, 3, 4, 5).iterator takeWhileIncl (_ < 4)
res0: Iterator[Int] = non-empty iterator
scala> res0.toList
res1: List[Int] = List(1, 2, 3, 4)
You can roll your own fold over a pair like this:
scala> implicit def Pair_Is_Foldable[A, B](pair: (A, B)) = new {
| def fold[C](f: (A, B) => C): C = f.tupled(pair)
| }
Pair_Is_Foldable: [A, B](pair: (A, B))java.lang.Object{def fold[C](f: (A, B) => C): C}
class IteratorExtension[T](i : Iterator[T]) {
def takeWhileInclusive(predicate:(T) => Boolean) = new Iterator[T] {
val it = i
var isLastRead = false
def hasNext = it.hasNext && !isLastRead
def next = {
val res = it.next
isLastRead = !predicate(res)
res
}
}
}
And there's an error in your implicit. Here it is fixed:
object ImplicitIterator {
implicit def extendIterator[T](i : Iterator[T]) = new IteratorExtension(i)
}
scala> List(0,1,2,3,4,5,6,7).toStream.filter (_ < 6).take(2)
res8: scala.collection.immutable.Stream[Int] = Stream(0, ?)
scala> res8.toList
res9: List[Int] = List(0, 1)
After your update:
scala> def timeConsumeDummy (n: Int): Int = {
| println ("Time flies like an arrow ...")
| n }
timeConsumeDummy: (n: Int)Int
scala> List(0,1,2,3,4,5,6,7).toStream.filter (x => timeConsumeDummy (x) < 6)
Time flies like an arrow ...
res14: scala.collection.immutable.Stream[Int] = Stream(0, ?)
scala> res14.take (4).toList
Time flies like an arrow ...
Time flies like an arrow ...
Time flies like an arrow ...
res15: List[Int] = List(0, 1, 2, 3)
timeConsumeDummy is called 4 times. Am I missing something?