Why is Unit in PureScript's Prelude {} in JavaScript? - purescript

I'm a beginner to FP and Type-level programming.
I learned Void and Unit recently.
Prelude's unit is defined as {} in JavaScript.
"use strict";
exports.unit = {};
My question is "Why not null but {}?"
Maybe this is a trivial question, but I'd like to learn its philosophy.
From my understanding, unit corresponds to null in JavaScript.
For example, I can call a function with no arguments in JavaScript.
// hello :: Void -> String
function hello () {
return "hello"
}
const h1 = hello() // "hello"
// However, I do not have any members of `Void` in PureScript, so I cannot call like above.
If I have to specify some arguments of hello function, I choose null rather than {}.
// hello :: forall a. a -> String
function hello (a) {
return "hello"
}
// 'hello :: Unit -> String'-like
const h1 = hello(null) // "hello"
// undefined also works, but weird to me
const h2 = hello(undefined)
// also works, but weird
const h3 = hello(42)
const h4 = hello({})
const h5 = hello([])
If unit represents a side-effect, probably is it undefined or something null?
// 'log1 :: String -> Effect Void'-like
function log1 (s) {
return s => () => console.log(s) // console.log return undefined
}
// however, function must return a value
// 'log2 :: String -> Effect Unit'-like
function log2 (s) {
return s => () => {
console.log(s) // side-effect
return null
}
}
// foreign Effect.Console.log (ECMAScript-style)
function log3 (s) {
return s => () => {
console.log(s)
return {} // weird to me; it seems like 'return 42'
}
}
Am I missing something?

It doesn't actually matter what value you use for Unit. {} is a pretty arbitrary choice - undefined or null, or just not returning a value are all fine too if you're writing something in the FFI. Since Unit is only supposed to have one inhabitant, there's never a time that the actual runtime value for it is examined.
It's quite a long time since the choice of {} was made - it's probably a historical accident, leftover from the time that all non-Prim PS values were constructed as anonymous objects.

Related

How to solve TS2349 in a protractor test model

I've got the following test setup, but the transpiler is giving me the following error:
Error:(108, 9) TS2349:Cannot invoke an expression whose type lacks a call signature. Type '((opt_callback?: (value: Model1[]) => R | IThenable, opt_errback?: (error: any...' has no compatible call signatures.
// action class
export class SearchResultsActions {
// setup and other stuff
// Model1 and Model2 are both interfaces
getJSON(): promise.Promise<Array<Model1>> | promise.Promise<Array<Model2>> {
return option.getText().then((selected: string) => {
let searchType: "model1" | "model2" = "model1";
if (selected === "Model 2") {
searchType = "model2";
}
// getResultsEl returns an ElementArrayFinder
return ResultsPage.getResultsEl().map((el, index) => {
let pageObject: Model1PageObject | Model2PageObject = SearchPage.getResult(searchType, index);
let actionObject: Model1Actions | Model2Actions;
if (searchType === "model1") {
actionObject = new Model1Actions(<Model1PageObject> pageObject);
} else {
actionObject = new Model2Actions(<Model2PageObject> pageObject)
}
// both Model1Actions and Model2Actions have a getJSON() method
return actionObject.getJSON(); // returns a JSON object
});
});
}
}
In the search spec where the error is:
SearchResultsActions.getJSON()
.then((res: Array<Model1> | Array<Model2>) => {
// use lodash to perform equality
expect(_.isEqual(res, expected)).toBeTruthy();
});
The curious thing is, despite the error, the transpile works anyway and the tests pass. But I would like to not have the error blaring at me.
I'm using typescript 2.3.3, protractor 5.1.2
Any thoughts? Anywhere I can clarify?
The answer is to change the return type to
promise.Promise<Array<Model1> | Array<Model2>>
which is different from
promise.Promise<Array<Model1>> | promise.Promise<Array<Model2>>
which doesn't work.
Apparently this is true for Observables as well.

Idiomatic way to check for parameter initialization

I have a variable param which has to be initialized at runtime.
Then, I have a part of the code which implements the following:
if (param has been initialized)
...do something...
else
print error and exit
What is the most idiomatic way to do this in Scala?
So far I have used Option[X] in this way:
var param : Option[TheType] = None
...
val param_value : TheType = x getOrElse {println("Error"); null}
But, since I have to return null it seems dirty.
How should I do it?
Simply map or foreach over it:
param.foreach { param_value =>
// Do everything you need to do with `param_value` here
} getOrElse sys.exit(3) # Param was empty, kill the program
You can also use the for comprehension style:
for {
param_value <- param
} yield yourOperation(param_value)
The upside of this is that if your calling code is expecting to do something with param_value as a return value from yourMethod you will encode the possibility of param_value not existing in your return type (it will be an Option[TheType] rather than a potentially null TheType.)
I might me wrong but it seems to me that the use of Future would fit with your problem: Instead of explicitly checking whether your required param_value has been initialized and finish the program if not, you could make your resource dependent code to execute when the resource has been rightly initialized:
val param: Future[TheType] = future {
INITIALIZATION CODE HERE
}
param onFailure {
case e => println("Error!");
}
param onSuccess {
case param_value: TheType => {
YOUR BUSINESS CODE HERE
}
}

rxjs zip is not lazy?

I 've removed the boilerplate to get to the point
// a.js
// My observables from stream and event
this.a = Rx.Node.fromStream(this.aStream());
this.itemSource = Rx.Observable.fromEvent(ee, 'addItem');
// Zip 'em
this.itemcombo = Rx.Observable.zip(this.a, this.itemSource, function (s1, s2) {
return {item: s2, a: s1.toString()};
});
// Streams the lowercase alphabet
rb.prototype.aStream = function aStream() {
var rs = Readable();
var c = 97;
rs._read = function () {
rs.push(String.fromCharCode(c++));
console.log('Hit!');
if (c > 'z'.charCodeAt(0)) {
rs.push(null);
}
};
return rs;
};
// b.js (requires the module exported above)
rb.enqueue('a'); // The method simply does an ee.emit('addItem', ...) in the module to trigger the itemSource observable
What I expected to see:
{item: 'a', a: 'a'} printed in the console
What happened:
Hit! was printed 24 times before {item: 'a', a: 'a'}. This means that zip took all the values from aStream, buffered them and then did what it was supposed to do.
How do I get the same functionality zip offers but lazily? My goal is to use an infinite stream/observable and zip it with a finite (async) one.
Edit
See/Edit it via runnable: RX Zip test Edit 2 Code updated based on answer -> no output now.
zip is indeed lazy. It just subscribes to a and b and does its work whenever either produces a new value.
Your problem is that fromStream is emitting all of its values synchronously as soon as zip subscribes to it. This is happening because your custom Readable is constantly saying "There is more data available!"
Make your Readable asynchronous and you'll get the desired behavior.
Try something like this (untested)
var rs = Readable();
var subscription = null;
rs._read = function () {
if (!subscription) {
// produce the values once per second
subscription = Rx.Observable
.generateWithRelativeTime(
97, // start value
function (c) { return c > 'z'.charCodeAt(0); }, // end condition
function (c) { return c + 1; }, // step function
function (c) { return String.fromCharCode(c); }, // result selector
function () { return 1000; }) // 1000ms between values
.subscribe(
function (s) {
rs.push(s);
console.log("Hit!");
},
function (error) { rs.push(null); },
function () { rs.push(null); });
}
};

How to write left outer join using MethodCallExpressions?

The code block below answers the question: "How do you perform a left outer join using linq extension methods?"
var qry = Foo.GroupJoin(
Bar,
foo => foo.Foo_Id,
bar => bar.Foo_Id,
(x,y) => new { Foo = x, Bars = y })
.SelectMany(
x => x.Bars.DefaultIfEmpty(),
(x,y) => new { Foo = x, Bar = y});
How do you write this GroupJoin and SelectMany as MethodCallExpressions? All of the examples that I've found are written using DynamicExpressions translating strings into lambdas (another example). I like to avoid taking a dependency on that library if possible.
Can the query above be written with Expressions and associated methods?
I know how to construct basic lambda expressions like foo => foo.Foo_Id using ParameterExpressions MemberExpressions and Expression.Lambda() , but how do you construct (x,y) => new { Foo = x, Bars = y })??? to be able to construct the necessary parameters to create both calls?
MethodCallExpression groupJoinCall =
Expression.Call(
typeof(Queryable),
"GroupJoin",
new Type[] {
typeof(Customers),
typeof(Purchases),
outerSelectorLambda.Body.Type,
resultsSelectorLambda.Body.Type
},
c.Expression,
p.Expression,
Expression.Quote(outerSelectorLambda),
Expression.Quote(innerSelectorLambda),
Expression.Quote(resultsSelectorLambda)
);
MethodCallExpression selectManyCall =
Expression.Call(typeof(Queryable),
"SelectMany", new Type[] {
groupJoinCall.ElementType,
resultType,
resultsSelectorLambda.Body.Type
}, groupJoinCall.Expression, Expression.Quote(lambda),
Expression.Quote(resultsSelectorLambda)));
Ultimately, I need to create a repeatable process that will left join n Bars to Foo. Because we have a vertical data structure, a left-joined query is required to return what is represented as Bars, to allow the user to sort Foo. The requirement is to allow the user to sort by 10 Bars, but I don't expect them to ever use more than three. I tried writing a process that chained the code in the first block above up to 10 times, but once I got passed 5 Visual Studio 2012 start to slow and around 7 it locked up.
Therefore, I'm now trying to write a method that returns the selectManyCall and calls itself recursively as many times as is requested by the user.
Based upon the query below that works in LinqPad, the process that needs to be repeated only requires manually handling the transparent identifiers in Expression objects. The query sorts returns Foos sorted by Bars (3 Bars in this case).
A side note. This process is significantly easier doing the join in the OrderBy delegate, however, the query it produces includes the T-SQL "OUTER APPLY", which isn't supported by Oracle which is required.
I'm grateful for any ideas on how to write the projection to anonymous type or any other out-of-the-box idea that may work. Thank you.
var q = Foos
.GroupJoin (
Bars,
g => g.FooID,
sv => sv.FooID,
(g, v) =>
new
{
g = g,
v = v
}
)
.SelectMany (
s => s.v.DefaultIfEmpty (),
(s, v) =>
new
{
s = s,
v = v
}
)
.GroupJoin (
Bars,
g => g.s.g.FooID,
sv => sv.FooID,
(g, v) =>
new
{
g = g,
v = v
}
)
.SelectMany (
s => s.v.DefaultIfEmpty (),
(s, v) =>
new
{
s = s,
v = v
}
)
.GroupJoin (
Bars,
g => g.s.g.s.g.FooID,
sv => sv.FooID,
(g, v) =>
new
{
g = g,
v = v
}
)
.SelectMany (
s => s.v.DefaultIfEmpty (),
(s, v) =>
new
{
s = s,
v = v
}
)
.OrderBy (a => a.s.g.s.g.v.Text)
.ThenBy (a => a.s.g.v.Text)
.ThenByDescending (a => a.v.Date)
.Select (a => a.s.g.s.g.s.g);
If you're having trouble figuring out how to generate the expressions, you could always get an assist from the compiler. What you could do is declare an lambda expression with the types you are going to query with and write the lambda. The compiler will generate the expression for you and you can examine it to see what expressions make up the expression tree.
e.g., your expression is equivalent to this using the query syntax (or you could use the method call syntax if you prefer)
Expression<Func<IQueryable<Foo>, IQueryable<Bar>, IQueryable>> expr =
(Foo, Bar) =>
from foo in Foo
join bar in Bar on foo.Foo_Id equals bar.Foo_Id into bars
from bar in bars.DefaultIfEmpty()
select new
{
Foo = foo,
Bar = bar,
};
To answer your question, you can't really generate an expression that creates an anonymous object, the actual type isn't known at compile time. You can cheat kinda by creating a dummy object and use GetType() to get its type which you could then use to create the appropriate new expression, but that's more of a dirty hack and I wouldn't recommend doing this. Doing so, you won't be able to generate strongly typed expressions since you don't know the type of the anonymous type.
e.g.,
var dummyType = new
{
foo = default(Foo),
bars = default(IQueryable<Bar>),
}.GetType();
var fooExpr = Expression.Parameter(typeof(Foo), "foo");
var barsExpr = Expression.Parameter(typeof(IQueryable<Bar>), "bars");
var fooProp = dummyType.GetProperty("foo");
var barsProp = dummyType.GetProperty("bars");
var ctor = dummyType.GetConstructor(new Type[]
{
fooProp.PropertyType,
barsProp.PropertyType,
});
var newExpr = Expression.New(
ctor,
new Expression[] { fooExpr, barsExpr },
new MemberInfo[] { fooProp, barsProp }
);
// the expression type is unknown, just some lambda
var lambda = Expression.Lambda(newExpr, fooExpr, barsExpr);
Whenever you need to generate an expression that involves an anonymous object, the right thing to do would be to create an known type and use that in place of the anonymous type. It will have limited use yes but it's a much cleaner way to handle such a situation. Then at least you'll be able to get the type at compile time.
// use this type instead of the anonymous one
public class Dummy
{
public Foo foo { get; set; }
public IQueryable<Bar> bars { get; set; }
}
var dummyType = typeof(Dummy);
var fooExpr = Expression.Parameter(typeof(Foo), "foo");
var barsExpr = Expression.Parameter(typeof(IQueryable<Bar>), "bars");
var fooProp = dummyType.GetProperty("foo");
var barsProp = dummyType.GetProperty("bars");
var ctor = dummyType.GetConstructor(Type.EmptyTypes);
var newExpr = Expression.MemberInit(
Expression.New(ctor),
Expression.Bind(fooProp, fooExpr),
Expression.Bind(barsProp, barsExpr)
);
// lambda's type is known at compile time now
var lambda = Expression.Lambda<Func<Foo, IQueryable<Bar>, Dummy>>(
newExpr,
fooExpr,
barsExpr);
Or, instead of creating and using a dummy type, you might be able to use tuples in your expressions instead.
static Expression<Func<T1, T2, Tuple<T1, T2>>> GetExpression<T1, T2>()
{
var type1 = typeof(T1);
var type2 = typeof(T2);
var tupleType = typeof(Tuple<T1, T2>);
var arg1Expr = Expression.Parameter(type1, "arg1");
var arg2Expr = Expression.Parameter(type2, "arg2");
var arg1Prop = tupleType.GetProperty("Item1");
var arg2Prop = tupleType.GetProperty("Item2");
var ctor = tupleType.GetConstructor(new Type[]
{
arg1Prop.PropertyType,
arg2Prop.PropertyType,
});
var newExpr = Expression.New(
ctor,
new Expression[] { arg1Expr, arg2Expr },
new MemberInfo[] { arg1Prop, arg2Prop }
);
// lambda's type is known at compile time now
var lambda = Expression.Lambda<Func<T1, T2, Tuple<T1, T2>>>(
newExpr,
arg1Expr,
arg2Expr);
return lambda;
}
Then to use it:
var expr = GetExpression<Foo, IQueryable<Bar>>();

Object from comprehension in CoffeeScript [dict/hash comprehensions]

is there a way to return an object from a comprehension in coffeescript? something so that i could express this:
form_values = () ->
ret = {}
ret[f.name] = f.value for f in $('input, textarea, select')
return ret
like this:
form_values = () -> f.name, f.value for f in $('input, textarea, select')
i'd like to construct a single object (not an array of objects). so if the markup looks something like this:
<form name=blah>
<input type=text name=blah1 value=111 />
<textarea name=blah2>222</textarea>
<select name=blah3>
<option value=333a>
<option value=333b>
</select>
</form>
the returned object would be something like this:
{
blah1: '111',
blah2: '222',
blah3: ''
}
form_values = new ->
#[f.name] = f.value for f in $ 'input, textarea, select'
this
or
form_values = new class then constructor: ->
#[f.name] = f.value for f in $ 'input, textarea, select'
Nope. Comprehensions only return arrays in CoffeeScript. Search the issue tracker for object comprehensions, and you'll find several proposals, but none were found suitable.
Check the functional library underscore and the extension _.mash from this mixin:
form_values = ->
_($('input, textarea, select')).mash f -> [f.name, f.value]
Using underscore's object function, you can do this:
form_values = _.object([f.name, f.value] for f in $('input, textarea, select'))
This has already been answered but probably lack of some explanations as this idiom is rather cryptic at first sight:
form_values = (new -> #[f.name] = f.value for f in $ 'input, textarea, select'; #)
// ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^
// create with |
// a new that |
// empty anonymous |
// object constructor |
// don't forget -/
// to return the
// newly created object
The key idea is to create an empty object (new) with an anonymous constructor (-> ...) that will create the various fields.
CoffeeScript's creator suggests using a helper function to convert an array of pairs into an object:
form_values = toObject([f.name, f.value] for f in $('input, textarea, select'))
This is arguably the most readable way of doing it, within the current language syntax. It's also very similar to how Python and other languages do it, except for the missing syntactic sugar.
The helper function can be easily written once, using for example the technique from #matyr's and #Sylvain's answers:
// Create a new object from an array of [key, value] pairs.
toObject = (pairs) ->
new -> #[key] = value for [key, value] in pairs; #
I believe you can do this with no added libraries right in CoffeeScript.
It should be something to the effect of:
$('input, textarea, select').each (item) => #form_values || #form_values = {}; #form_values[$(item).name] = $(item).value
You could simplify the syntax of that by pre-creating the form_values:
form_values = {}
$('input, textarea, select').each (item) -> form_values[$(item).name] = $(item).value
Here is a lengthier response with canned examples:
Take a very simple example where you wanted to map the obj to name value:
items = [ { a: 1 }, { b: 2 }, { c: 3 } ]
items.map((item) -> {name: Object.keys(item)[0], value: item[Object.keys(item)[0]]})
[ { name: 'a', value: 1 },
{ name: 'b', value: 2 },
{ name: 'c', value: 3 } ]
Note that the above is not really an Object comprehension, just demonstrating an example.
Now let's say there is a bit more structure and you just want to map a known unique key:
items = [{key: "abc", someVar: 1}, {key: "def", someVar: 2}]
In Python you'd do something simple like this: {x['key']:x for x in items}
In CoffeeScript you can get all of this down to one single line though with a caveat:
items.forEach (item) => #x || #x = {}; #x[item['key']] = item
{ abc: { key: 'abc', someVar: 1 },
def: { key: 'def', someVar: 2 } }
In the above code x was not previously defined in the scope, so using => and # allowed us to bind x with the #x || #x = {} if not previously found, then set the key.
If you don't want to use => and # you have to define x beforehand:
x = {}
items.forEach (item) => x || x = {}; x[item['key']] = item
{ abc: { key: 'abc', someVar: 1 },
def: { key: 'def', someVar: 2 } }
Not to beat a dead horse, but I personally thing this is readable and satisfies the 'one line' requirement without needing extra modules:
form_values = {}; form_values[f.name] = f.value for f in $('input, textarea, select')
Don't forget you can still use a semi-colon to combine lines in Coffeescript!