PureScript - Splitting Array of Positive and Negative Numbers into Tuple of 2 Arrays of Positive and Negative Numbers - purescript

I'm a newbie in PureScript now reading a book "Functional Programming Made Easier: A Step-by-Step Guide", but when I got to the section on Tuples, I realised that all that was presented appeared to be nonsense.
This is the code that's presented that does not work.
splitPosAndNeg :: Array Int -> Tuple (Array Int) (Array Int)
let Tuple pos neg = splitPosAndNeg [1, -2, 3, -4, 5, -6, -7, 8]
let split = splitPosAndNeg [1, -2, 3, -4, 5, -6, -7, 8]
pos = fst split
neg = snd split
Could someone explain how to split an Array of Positive and Negative Numbers into a Tuple of 2 Arrays of Positive and Negative Numbers using PureScript? Would partition from Data.Array work? How is it used?
#Fyodor Soikin, I've tried out the book's code here with the partition function. It still does not work.

I don't have the book, so it's very hard to say where the disconnect is.
But from snippet you posted, it kind of looks like the author is merely asserting that such function exists in the scope, without giving its implementation, because it's not important for the context. And to clarify what the function does, the author gives its type signature.
splitPosAndNeg :: Array Int -> Tuple (Array Int) (Array Int)
And then the author shows two examples of how the result of such function might be used. First example - by pattern-matching on the Tuple constructor:
let Tuple pos neg = splitPosAndNeg [1, -2, 3, -4, 5, -6, -7, 8]
And second example - by using fst and snd functions to obtain the first and second elements of the tuple respectively:
let split = splitPosAndNeg [1, -2, 3, -4, 5, -6, -7, 8]
pos = fst split
neg = snd split
(note that you probably have screwed up indentation in your snippet: pos and neg should be aligned under split)
In response to your comment:
Thanks, but the code still does not work. Please refer to my link in my updated post about my problem above. The link is too long to paste in a comment box.
A let binding cannot be at top level, it has to be in a function body. Plus, the function implementation you added has the wrong type. Here, I fixed it for you.

I've just found the answer to my problem using the partition function from the Data.Array module.
partition (_ > 0) [1, -2, 3, -4, 5, -6, -7, 8]
-- { no: [-2,-4,-6,-7], yes: [1,3,5,8] }

Related

How does sortWith in Scala work in terms of iterating a tuple?

A list can be iterated as follows:
scala> val thrill = "Will" :: "fill" :: "until" :: Nil
val thrill: List[String] = List(Will, fill, until)
scala> thrill.map(s => s + "y")
val res14: List[String] = List(Willy, filly, untily)
The above code first creates a list and then the second command creates a map with an iterable called as 's', the map creates a new string from 's' by appending the char 'y'.
However, I do not understand the following iteration process:
scala> thrill.sortWith((s,t) => s.charAt(0).toLower < t.charAt(0).toLower)
val res19: List[String] = List(fill, until, Will)
Does the tuple (s,t) take two elements of thrill at once and compares them? How is sorting performed exactly using this syntax/function?
Sorting is arranging the data in ascending or descending order. Sorted data helps us searching easily.
Scala uses TimSort, which is a hybrid of Merge Sort and Insertion Sort.
Here is signature of sortWith function in scala -
def sortWith(lt: (A, A) => Boolean): Repr
The sortWith function Sorts this sequence according to a comparison function. it takes a comparator function and sort according to it.you can provide your own custom comparison function.
It will perform Tim Sort on the input list to result sorted output.
Yes the function compares two elements at a time to determine their ordering.
The implementation of sortWith falls back on Java's Array.sort (docs) with the following signature
sort(T[] a, Comparator<? super T> c)
which takes in an Array of T and a comparator, equipped with a binary function that can compare any two elements of the set of possible values of T and give you some information about how they relate to each other (as in should come before, same or after based on your function).
Behind the scenes it is really just an iterative merge sort details of which can be found on the wikipedia page for merge sort
Leaving the optimizations aside, if you aren't familiar with it, merge sort, which is a divide and conquer algorithm, simply breaks down the collection you have until you have groups of 2 elements and then merges the smaller lists in a sorted way simply by comparing 2 elements at a time, which is where the binary comparison function you pass in comes to play.
i.e.
List(4, 11, 2, 1, 9, 0) //original list
Break down to chunks:
[4, 11], [2, 1], [9, 0]
Sort internally:
[4, 11], [1, 2], [0, 9]
Merge:
[1, 4, 11], [2], [0, 9]
[1, 2, 4, 11], [0, 9]
[0, 1, 2, 4, 11], [9]
[0, 1, 2, 4, 9, 11]
P.S. a nit picky detail, sortedWith takes in a Function2 (a function of arity 2). This function you pass in is used to generate what we call an Ordering in Scala, which is then implicity converted to a Comparator. Above, I have linked to the implementation of sorted which is what sortedWith calls once it generates this ordering and which is where most of the sorting logic happens.

Is there a numpy api for transforming & flat-mapping rows of 2d array?

Suppose I have a 2d numpy array of positive integers:
[[1, 3]
[2, 7]]
and to each element I would like to apply a function which transforms it into a sequence of integers, giving me:
[[[0,0,1],[0,1,1]]
[[0,1,0],[1,1,1]]]
that I would like to have then flattened row-wise to:
[[0, 0, 1, 0, 1, 1]
[0, 1, 0, 1, 1, 1]]
I know this can be done step-by-step, but maybe there's a better, efficient both memory- and cpu-time wise Numpy/SciPy api for transformations like described above?
Thanks!
I've come with this, but it is far from elegant and concise in my book:
def fn(x):
return np.array([int(c) for c in '{0:08b}'.format(x)])
F = np.frompyfunc(fn, 1, 1)
a = np.arange(6).reshape((2, 3))
np.vstack(np.hstack(F(a))).reshape((2, 24))
It is really difficult to comprehend there's no easier way than frompyfunc and combined hstack & vstack

Scala: How to multiply a List of Lists by value

Now studying Scala and working with list of lists. Want to multiply array by an element(for example, 1).
However I get the following error:
identifier expected but integer constant found
Current code:
def multiply[A](listOfLists:List[List[A]]):List[List[A]] =
if (listOfLists == Nil) Nil
else -1 * listOfLists.head :: multiply(listOfLists.tail)
val tt = multiply[List[3,4,5,6];List[4,5,6,7,8]]
print(tt);;
There are a few issues with your code:
In general, you can't perform arithmetic on unconstrained generic types; somehow, you have to communicate any supported arithmetic operations.
Multiplying by 1 will typically have no effect anyway.
As already pointed out, you don't declare List instances using square brackets (they're used for declaring generic type arguments).
The arguments you're passing to multiply are two separate lists (using an invalid semicolon separator instead of a comma), not a list of lists.
In the if clause the return value is Nil, which matches the stated return type of List[List[A]]. However the else clause is trying to perform a calculation which is multiplying List instances (not the contents of the lists) by an Int. Even if this made sense, the resulting type is clearly not a List[List[A]]. (This also makes it difficult for me to understand exactly what it is you're trying to accomplish.)
Here's a version of your code that corrects the above, assuming that you're trying to multiply each member of the inner lists by a particular factor:
// Multiply every element in a list of lists by the specified factor, returning the
// resulting list of lists.
//
// Should work for any primitive numeric type (Int, Double, etc.). For custom value types,
// you will need to declare an `implicit val` of type Numeric[YourCustomType] with an
// appropriate implementation of the `Numeric[T]` trait. If in scope, the appropriate
// num value will be identified by the compiler and passed to the function automatically.
def multiply[A](ll: List[List[A]], factor: A)(implicit num: Numeric[A]): List[List[A]] = {
// Numeric[T] trait defines a times method that we use to perform the multiplication.
ll.map(_.map(num.times(_, factor)))
}
// Sample use: Multiply every value in the list by 5.
val tt = multiply(List(List(3, 4, 5, 6), List(4, 5, 6, 7, 8)), 5)
println(tt)
This should result in the following output:
List(List(15, 20, 25, 30), List(20, 25, 30, 35, 40))
However, it might be that you're just trying to multiply together all of the values in the lists. This is actually a little more straightforward (note the different return type):
def multiply[A](ll: List[List[A]])(implicit num: Numeric[A]): A = ll.flatten.product
// Sample use: Multiply all values in all lists together.
val tt = multiply(List(List(3, 4, 5, 6), List(4, 5, 6, 7, 8)))
println(tt)
This should result in the following output:
2419200
I'd recommend you read a good book on Scala. There's a lot of pretty sophisticated stuff going on in these examples, and it would take too long to explain it all here. A good start would be Programming in Scala, Third Edition by Odersky, Spoon & Venners. That will cover List[A] operations such as map, flatten and product as well as implicit function arguments and implicit val declarations.
To make numeric operations available to type A, you can use context bound to associate A with scala.math.Numeric which provides methods such as times and fromInt to carry out the necessary multiplication in this use case:
def multiply[A: Numeric](listOfLists: List[List[A]]): List[List[A]] = {
val num = implicitly[Numeric[A]]
import num._
if (listOfLists == Nil) Nil else
listOfLists.head.map(times(_, fromInt(-1))) :: multiply(listOfLists.tail)
}
multiply( List(List(3, 4, 5, 6), List(4, 5, 6, 7, 8)) )
// res1: List[List[Int]] = List(List(-3, -4, -5, -6), List(-4, -5, -6, -7, -8))
multiply( List(List(3.0, 4.0), List(5.0, 6.0, 7.0)) )
// res2: List[List[Double]] = List(List(-3.0, -4.0), List(-5.0, -6.0, -7.0))
For more details about context bound, here's a relevant SO link.

Create Spark dataset with parts of other dataset

I'm trying to create a new dataset by taking intervals from another dataset, for example, consider dataset1 as input and dataset2 as output:
dataset1 = [1, 2, 3, 4, 5, 6]
dataset2 = [1, 2, 2, 3, 3, 4, 4, 5, 5, 6]
I managed to do that using arrays, but for mlib a dataset is needed.
My code with array:
def generateSeries(values: Array[Double], n: Int): Seq[Array[Float]] = {
var res: Array[Array[Float]] = new Array[Array[Float]](m)
for(i <- 0 to m-n){
res :+ values(i to i + n)
}
return res
}
FlatMap seems like the way to go, but how a function can search for the next value in the dataset?
The problem here is that an array is in no way similar to a DataSet. A DataSet is unordered and has no indices, so thinking in terms of arrays won't help you. Go for a Seq and treat it without using indices and positions at all.
So, to represent an array-like behaviour on a DataSet you need to create your own indices. This is simply done by pairing the value with the position in the "abstract array" we are representing.
So the type of your DataSet will be something like [(Int,Int)], where the first is the index and the second is the value. They will arrive unordered, so you will need to rework your logic in a more functional way. It's not really clear what you're trying to achieve but I hope I gave you an hint. Otherwise explain better the expected result in the comment to my answer and I will edit.

Reading the syntax off of this listing at scala-lang

Just learning some basic stuff here.
It appears the count method for Vector will be useful to me for an exercise I'm working on, but from reading its entry at scala-lang I'm having a hard time understanding exactly how to use it, syntactically speaking.
Here's what the entry says:
count(p: (A) => Boolean): Int
I think that's supposed to be telling me the syntax to use when calling the method.
It tells me that "p" is the predicate to be satisfied. Okay, I know what a predicate is in the abstact. What does a predicate look like in Scala though?
Then there's a colon. Do I type that? Or is this meta-linguistic notation of some kind?
Then there's a rocket. Okay. Then that word Boolean--but what is it doing there? I assume I don't literally type "Boolean." (Do I?)
Anyway, hopefully you see my problem(s).
How does this work?
You are almost there!
count needs a parameter p of type (:) A to (rocket) Boolean, where 'A' is the type of elements stored by the vector. So you have to provide a function from A to Boolean.
So you can use it like this:
val v = Vector(1, 2, 3, 4, 5, 6) // == Vector[Int](1, 2, 3, 4, 5, 6)
def odd(elem: Int): Boolean = {
elem % 2 == 0
}
v.count(odd) // == 3
Or using some syntactic sugar:
val v = Vector(1, 2, 3, 4, 5, 6) // == Vector[Int](1, 2, 3, 4, 5, 6)
v.count(_ % 2 == 0) // == 3