Convert an array to a list in PureScript - arrays

XY problem
How do I convert an array to a list in PureScript?
arrayToList :: forall a. Array a -> List a
arrayToList = ???
Actual problem
Must I necessarily write this function?
Neither purescript-arrays nor purescript-lists define such a function, which leads me wonder if there is an idiomatic way to deal with arrays in the contexts of functions taking a list.
For example Matrix.getRow returns an array which needs to be transformed into a list of Pux Html elements (in the process of rendering the matrix as HTML). What is the best way to do this?

With compiler version 0.10.2, you can simply write
arrayToList :: forall a. Array a -> List a
arrayToList = ?whatGoesHere
and the compiler will give you a list of things to fill in, based on the type information. ?whatGoesHere is called a typed hole.
In this case, you probably want Data.Array.toUnfoldable or Data.List.fromFoldable.

Related

When to use slice instead of an array in GO

I am learning GO. According to documentation, slices are richer than arrays.
However, I am failing to grasp hypothetical use cases for slices.
What would be use case where one would use a slice instead of array?
Thanks!
This is really pretty elementary and probably should already have been covered in whatever documentation you're reading (unless it's just the language spec), but: A Go array always has a fixed size. If you always need 10 things of type T, [10]T is fine. But what if you need a variable number of things n, where n is determined at runtime?
A Go slice—which consists of two parts, a slice header and an underlying backing array—is pretty ideal for holding information needed to access a variable-sized array. Note that just declaring a slice-header variable:
var x []T
doesn't actually allocate any array of T yet: the slice header will be initialized to hold nil (converted to the right type) as the (missing) backing array, 0 as the current size, and 0 as the capacity of this array. As a result of this, the test x == nil will say that yes, x is nil. To get an actual array, you will need either:
an actual array, or
a call to make, or
use of the built-in append or similar (e.g., copy, append hidden behind some function, etc).
Since the call to make happens at runtime, it can make an array of whatever size is needed at this point. A series of calls to append can build up an array. Note that each call to append may have to allocate a new backing array, or may be able to extend the existing array in-place, depending on what's in the capacity. That's why you need x = append(x, elem) or x = append(x, elems...) and not just append(x, elem) or append(x, elems...).
The Go blog entry on slices has a lot more to say on this. I like this page more than the sequence of pages in the Go Tour starting here, but opinions vary.

Modify fixed-size array within List Element

I'm doing a micro-optimisation of my LRU cache solution in Golang where I'm using https://golang.org/pkg/container/list/. My solution works by having a map[int]*list.Element, where each list.List list.Element is []int, with [0] being key, and [1] being value.
I'm trying to move from []int to [2]int for my optimisation, but I'm then running into the issue that modifying the fixed-size array, after ee := e.Value.([2]int) (note the [2]int type for fixed-size array), is no longer modifying the underlying values in the list.Element, unlike was the case w/ ee := e.Value.([]int) (note the []int type), which I guess makes perfect sense, since slices are based on references, whereas fixed-size arrays are based on copied values.
I've tried stuff like e.Value.([2]int)[1] = …, as well as various combinations with := &e.Value…, and casting from [2]int to []int, but it all results in complier errors.
Q: Is there no way to use the container/list with an embedded array, and perform modifications of said fixed-size array in-place?
As you already noted:
I guess makes perfect sense, since slices are based on references, whereas fixed-size arrays are based on copied values
So if you want to make this work, you'll need to use references to your fixed-size arrays by storing pointers to the arrays instead of array values.
That way, you'll be able to modify the underlying array through the list element.
See here for a simple example:
package main
import (
"container/list"
"fmt"
)
func main() {
l := list.New()
// create a fixed size array and initialize it
var arr [2]int
arr[0] = 1
arr[1] = 2
// push a pointer to the array into the list
elem := l.PushFront(&arr)
// modify the stored array
elem.Value.(*[2]int)[0] = 3
// print the element from iterating the list
for e := l.Front(); e != nil; e = e.Next() {
fmt.Println(e.Value)
}
// print the underlying array, both are modified
fmt.Println(arr)
}
EDIT
Note that this behaviour is not something specific to this list implementation, but rather related how type assertions work in the language itself.
See here:
https://golang.org/doc/effective_go.html#interface_conversions
Quoting from that section (and adding emphasis of my own):
The syntax borrows from the clause opening a type switch, but with an explicit type rather than the type keyword: value.(typeName) and the result is a new value with the static type typeName.
When using reference types, copying the value does not affect you cause copying a pointer value ends up allowing you to change the same underlying reference.
But when the array is a value itself, it does not make sense to assign to the copy. When you try to modify the array directly (without assigning the type assertion to a variable) Go would even catch this at compile time so that you don't assign to this "temporary" copy which would obviously be a mistake. That's how you got all your syntax errors when trying to do this.
To overcome this (if you don't want to use pointers) one possibility might be for you to implement your own list, borrowing from the implementation you are using but making your Element's value an explicit [2]int instead of an interface.
That would remove the need to make the type assertion and you'll be able to modify the underlying array.

Function which accepts array of arbitrary size as argument (is it possible in Golang?)

Q: Is there a way, in golang, to define a function which accepts an array of arbitrary length as argument?
e.g.,
function demoArrayMagic(arr [magic]int){
....
}
I have understood that in golang, array length is part of the variable type, for this reason the following function is not going to accept one arbitrary array as input
function demoArray(arr [2]int){
....
}
This function is not going to compile with arrInput [6]int as input--i.e., demoArray(arrInput) will fail to compile.
Also the following function, which accepts a slice argument, does not accept arrays as arguments (different types, as expected):
function demoSlice(arr []int){
....
}
i.e., demoSlice(arrInput) does not compile, expects a slice not an array.
The question is, is there a way to define a function that takes arrays of arbitrary length (arrays, NOT slice)? It looks quite strange and limiting for a language to impose this constraint.
The question makes sense independently from the motivation, but, in my case, the reason behind is the following. I have a set of functions which takes as arguments data structures of type [][]int.
I noticed that GOB serialization for them is 10x slower (MB/s) than other data structures I have. I suppose that may be related to the chain of derefencing operations in slices. Moving from slices to array--i.e.,defining objects of type [10000][128]int--may improve situation (I hope).
Regards
P.s: I remind now that Go, passes/uses things 'by value', using arrays may be overkill cause golang is going to copy them lot of times. I think I'll stay with slices and I'll try to understand GOB internals a bit.
There is not. Go does not support generics.
The only way would be to use interface{}, but that would allow to pass a value of any type, not just arrays of your desired type.
Arrays in Go are "secondary". The solution is to use slices for your requirement.
One thing to note here is that you may continue to use arrays, and only slice them when you want to pass them to this function, e.g.:
func main() {
a1 := [1]int{1}
demo(a1[:])
a2 := [2]int{1, 2}
demo(a2[:])
}
func demo(s []int) {
fmt.Println("Passed:", s)
}
Output of the above (try it on the Go Playground):
Passed: [1]
Passed: [1 2]

In order to preallocate memory in Matlab, I want to initialize my array of objects. How do I do this?

I have a class of objects known as blocks. Currently, I am creating an array of blocks using a for loop by simply tacking them unto an empty array
blockArray=[];
for ii=1:Size
blockArray=[blockArray block(....)];
end
In order to preallocate memory, how do I initialize an object array of blocks with dummy values?
For instance if instead of using block objects I used numbers, I could easily preallocate by using zeros(1,Size). Is there something similar that I could do?
The matlab documentation describes
To preallocate the object array, assign the last element of the array first. MATLAB® fills the first to penultimate array elements with default DocArrayExample objects.
So, to do this, instead of iterating over from 1:size, it is simpler to do...
blockArray = []
blockArray(size) = block(...)
The language does not really support this, there exists multiple solutions (or workarounds).
Replicating the first instance
When pushing the first element into the array, you can fill the whole array with this element to achieve a preallocation. This might look very bad, but it is actually the fastest possibility known to me.
for ii=1:S
%assumption e is a scalar, otherwise the code is totally screwed
e=block(....)
if ii==1
%to do preallocation, fill it with your first element
blockArray(1:S)=e
else
blockArray(ii)=e
end
end
Use cell arrays
Obvious simple solution, you can put any class into the fields
blockArray=cell(S,1);
for ii=1:S
%assumption e is a scalar, otherwise the code is totally screwed
e=block(....)
blockArray{ii}=e
end
This solution is very simple but slower than the first. You also lose some functionality which is not available for cell arras
Let your class implement array functionality
classdef A
properties
arg1
out
end
methods
function obj = A(varargin)
if nargin==0
%null object constructor
elseif strcmpi(varargin{1},'createarray')
sz=varargin(2:end);
%preallocate
obj(sz{:})=A;
else
%standard constructor
obj.arg1=varargin{1};
obj.out=[1 2 3;];
end
end
end
end
Constructor with no input argument creates an "empty" or "null" object, this is used to preallocate so it should be empty.
Constructor with first parameter makearray creates an array
Otherwise your constructor should be called.
Usage:
%create an empty object
A
%create an array of size 2,3,4
A('createarray',2,3,4)
%use the standard constructor
A(2)
Biggest downside is you have to modify your classes. Never tested this solution, but it should be close to the first in performance.

Passing a MathLink Function Lists With Different Structures

I've been developing a MathLink application with a function that accepts two lists, e.g.
:Pattern: g[zi_List, fi_List]
which I intended to pull in to the function manually. Both lists can be real or complex with the result being complex if either parameter is complex. Additionally, fi could be a list of square matrices, but zi is to remain a one dimensional list.
Within the MathLink C API, the most straightforward seeming function to use is MLGetReal64Array which can handle both real and complex data types as Complex shows up as the innermost Head of the array. And, once complexity is determined, the array can be cast to std::complex<double> or the C99 complex type, if appropriate. Now, MLGetReal64Array doesn't handle non-rectangular Lists, so each List element must have the dimensionality of the others and be of the same type: real of complex. Oddly, though, with a function that accepts a single List parameter, MLGetReal64Array returns a data structure that has a one element List as its outermost element, i.e. inputing h[ {1, 3, 5} ] returns List[List[1,3,5]] on the c-side of things.
It turns out that for a two list function, like g, a single call to MLGetReal64Array will return both parameters at once, i.e. g receives List[ zi, fi ]. Since I plan on preprocessing each list for uniformity of structure and element type, ensuring that both had the same element type wouldn't be a problem. But, I'd like for fi to be a list of matrices, and MLGetReal64Array causes a MLEGSQ: MLGet() called out of sequence error.
So, my questions are: can I use MLGetReal64Array to get both lists? how would I go about it? And, if I can't use MLGetReal64Array, what are my alternatives?
I'm thinking that if MLGetReal64Array is correct about the structure, I can pop the outer List off the link by using MLGetFunction which would then allow me to use MLGetReal64Array for each parameter. As of yet, I haven't tried it. But, in the meantime, I would appreciate any suggestions.
I'd create separate functions for the different cases you have. It's much easier to handle this logic on the Mathematica side than figure out what you have coming over the link in C.

Resources