Is it possible to generically implement the amb operator in D? - ambiguity

Is it possible to generically implement the amb operator in D?
http://www.haskell.org/haskellwiki/Amb
http://www.randomhacks.net/articles/2005/10/11/amb-operator
The sort of thing I'm thinking of is:
amb([1, 2]) * amb([3, 4, 5]) == amb([3, 4, 5, 6, 8, 10])
amb(["hello", "world"]) ~ amb(["qwerty"]) == amb(["helloqwerty", "worldqwerty"])
amb(["hello", "world"]) ~ "qwerty" == amb(["helloqwerty", "worldqwerty"])
amb(["hello", "very long string"]).length = amb([5, 16])
In the last two examples, there really needs to be a 'lifting' of the ~ and .length into the amb 'context' (a monad?). In the first two examples, the operators should just be applied to the amb's contents.
I've given it a brief try, but I'm having problems when trying to lift the wrapped-type's operators/methods/properties (*, ~ and .length in this example). How should this be done in D?
Thanks,
Chris.

Yes, it is possible. Here's what I came up with.
import std.range;
import std.algorithm;
import std.stdio;
import std.functional;
import std.math;
import std.string;
struct AmbRange(R1, R2, alias Op)
{
public:
this(R1 _r1, R2 _r2) { r1 = _r1; r2 = r2c = _r2; }
void popFront()
{
r2.popFront();
if (r2.empty) { r2 = r2c; r1.popFront(); }
}
#property auto front() { return Op(r1.front, r2.front); }
#property bool empty() { return r1.empty; }
private:
R1 r1;
R2 r2, r2c;
}
struct Amb(R)
{
alias ElementType!(R) E;
public:
this(R r) { this.r = r; }
auto opBinary(string op, T)(T rhs) if (!is(T U : Amb!(U)))
{
alias binaryFun!("a"~op~"b") Op;
return map!((E e) { return Op(e, rhs); })(r);
}
auto opBinaryRight(string op, T)(T lhs) if (!is(T U : Amb!(U)))
{
alias binaryFun!("a"~op~"b") Op;
return map!((E e) { return Op(lhs, e); })(r);
}
auto opBinary(string op, T)(T rhs) if (is(T U : Amb!(U)))
{
alias binaryFun!("a"~op~"b") Op;
return AmbRange!(R, typeof(rhs.r), Op)(r, rhs.r);
}
auto opDispatch(string f, T ...)(T args)
{
mixin("return map!((E e) { return e."~f~"(args); })(r);");
}
auto opDispatch(string f)()
{
mixin("return map!((E e) { return e."~f~"; })(r);");
}
private:
R r;
}
auto amb(R)(R r) { return Amb!R(r); }
void main()
{
auto r1 = 2 * amb([1, 2, 3]);
assert(equal(r1, [2, 4, 6]));
auto r2 = amb(["ca", "ra"]) ~ "t";
assert(equal(r2, ["cat", "rat"]));
auto r3 = amb(["hello", "cat"]).length;
assert(equal(r3, [5, 3]));
auto r4 = amb(["cat", "pat"]).replace("a", "u");
assert(equal(r4, ["cut", "put"]));
auto r5 = amb([1, 2]) * amb([1, 2, 3]);
assert(equal(r5, [1, 2, 3, 2, 4, 6]));
}
Lots of thanks to BCS for figuring out how to resolve the binaryOp ambiguities.
I had to create a new range for traversing the result of a binary op between two Amb's, but I think that works out best anyway.
For those that are new to D, and are curious, all that string stuff is done at compile time, so there's no parsing code at runtime or anything like that -- it's pretty much as efficient as hand-coding it in C.

Related

How to save operators in Dart

I want to do something like this in dart.
var z = +
and then put it in another var like this
var x = 5 z 5
And when I did this
var z = +
I get an Error
Expected an identifier.
you can not make variable operators in dart though what you can do is to create a custom variable for the same by doing:
void main() {
var operators = {
'+': (a, b) { return a + b; },
'<': (a, b) { return a < b; },
// ...
};
var op = '+';
var x = operators[op]!(10, 20);
print(x);
}

How can you return null from orElse within Iterable.firstWhere with null-safety enabled?

Prior to null-safe dart, the following was valid syntax:
final list = [1, 2, 3];
final x = list.firstWhere((element) => element > 3, orElse: () => null);
if (x == null) {
// do stuff...
}
Now, firstWhere requires orElse to return an int, opposed to an int?, therefore I cannot return null.
How can I return null from orElse?
A handy function, firstWhereOrNull, solves this exact problem.
Import package:collection which includes extension methods on Iterable.
import 'package:collection/collection.dart';
final list = [1, 2, 3];
final x = list.firstWhereOrNull((element) => element > 3);
if (x == null) {
// do stuff...
}
You don't need external package for this instead you can use try/catch
int? x;
try {
x = list.firstWhere((element) => element > 3);
} catch(e) {
x = null;
}
A little bit late but i came up with this:
typedef FirstWhereClosure = bool Function(dynamic);
extension FirstWhere on List {
dynamic frstWhere(FirstWhereClosure closure) {
int index = this.indexWhere(closure);
if (index != -1) {
return this[index];
}
return null;
}
}
Example use:
class Test{
String name;
int code;
Test(code, this.name);
}
Test? test = list.frstWhere(t)=> t.code==123);
An alternative is that you set a nullable type to the list.
Instead of just [1, 2, 3], you write <int?>[1, 2, 3], allowing it to be nullable.
void main() {
final list = <int?>[1, 2, 3];
final x = list.firstWhere(
(element) => element != null ? (element > 3) : false,
orElse: () => null);
print(x);
}
This should work, and it's a better solution:
extension IterableExtensions<T> on Iterable<T> {
T? firstWhereOrNull(bool Function(T element) comparator) {
try {
return firstWhere(comparator);
} on StateError catch (_) {
return null;
}
}
}
To add to #Alex Hartfords answer, and for anyone who doesn't want to import a full package just for this functionality, this is the actual implementation for firstWhereOrNull from the collection package that you can add to your app.
extension FirstWhereExt<T> on List<T> {
/// The first element satisfying [test], or `null` if there are none.
T? firstWhereOrNull(bool Function(T element) test) {
for (final element in this) {
if (test(element)) return element;
}
return null;
}
}

How to avoid repetition expanding indices with macros in Rust?

Is there a way to write this macro that expands array access in such a way that larger arrays can be written in a less verbose way?
/// Avoid manually expanding an expression, eg:
///
/// let array = unpack!([some.vec; 3]);
///
/// Expands into: [some.vec[0], some.vec[1], some.vec[2]]
///
/// Supports expanding into different bracket types based on the input args.
macro_rules! unpack {
([$v_:expr; 2]) => { { let v = $v_; [v[0], v[1]] } };
(($v_:expr; 2)) => { { let v = $v_; (v[0], v[1]) } };
({$v_:expr; 2}) => { { let v = $v_; {v[0], v[1]} } };
([$v_:expr; 3]) => { { let v = $v_; [v[0], v[1], v[2]] } };
(($v_:expr; 3)) => { { let v = $v_; (v[0], v[1], v[2]) } };
({$v_:expr; 3}) => { { let v = $v_; {v[0], v[1], v[2]} } };
([$v_:expr; 4]) => { { let v = $v_; [v[0], v[1], v[2], v[3]] } };
(($v_:expr; 4)) => { { let v = $v_; (v[0], v[1], v[2], v[3]) } };
({$v_:expr; 4}) => { { let v = $v_; {v[0], v[1], v[2], v[3]} } };
}
To reduce verbosity you can construct recursive macro.
macro_rules! unpack {
({$vec:expr; $count:expr}) => {
unpack!([$vec; $count])
};
(($vec:expr; $count:expr)) => {
unpack!([$vec; $count])
};
([$vec:expr; $count:expr]) => {
$vec[0..$count]
};
}
fn main() {
let vec = vec![1, 2, 3, 4, 5];
assert_eq!([1, 2], unpack!({vec; 2}));
assert_eq!([1, 2, 3], unpack!((vec; 3)));
assert_eq!([1, 2, 3, 4], unpack!([vec; 4]));
}
Every macro can be called with (), [] and {} brackets, so if you don't need additional pair of brackets your macro can be as simple as that:
macro_rules! unpack {
($vec:expr; $count:expr) => {
$vec[0..$count]
};
}
fn main() {
let vec = vec![1, 2, 3, 4, 5];
assert_eq!([1, 2], unpack!{vec; 2});
assert_eq!([1, 2, 3], unpack!(vec; 3));
assert_eq!([1, 2, 3, 4], unpack![vec; 4]);
}
Example from Rust Book.

Is it possible to de-duplicate if statements and their body in Rust, perhaps by using macros?

Say we have a large block:
mod module {
pub const fiz: u32 = (1 << 0);
// etc...
}
flag = {
if (var & module::fiz) != 0 { module::fiz }
else if (var & module::foo) != 0 { module::foo }
else if (var & module::bar) != 0 { module::bar }
else if (var & module::baz) != 0 { module::baz }
// .. there could be many more similar checks
};
With simply replacement macro its possible to do:
#define TEST(f) ((var) & (f)) != 0 { f }
Allowing:
flag = {
if TEST(module::fiz)
else if TEST(module::foo)
else if TEST(module::bar)
else if TEST(module::baz)
}
It seems Rust doesn't allow a macro to declare part of an if statement.
I managed to avoid repetition using assignment, but its quite ugly.
flag = {
let f;
if (var & {f = module::fiz; f }) != 0 { f }
else if (var & {f = module::foo; f }) != 0 { f }
else if (var & {f = module::bar; f }) != 0 { f }
else if (var & {f = module::baz; f }) != 0 { f }
};
Does Rust provide some convenient/elegant way to allow repetition in this case?
I don't think flag checking is the important part of this question, the issue is that you may want to repeat content in the check again in the body of an if statement, e.g.:
if (foo && OTHER_EXPRESSION) { do(); something_with(OTHER_EXPRESSION) }
else if (foo && SOME_EXPRESSION) { do(); something_with(SOME_EXPRESSION) }
I think you have an X/Y problem here, so I am going to solve this without using if/else.
What you seem to be doing is checking for the presence of a bit pattern, and prioritise the order in which said patterns are checked for (unclear if it matters, but let's assume it does).
So, let's do this the functional way:
let constants = [fiz, foo, bar, baz];
let flag = constants.iter().filter(|v| var & *v == **v).next();
And it just works, no macro or repetitive stuff.
If you want to use macros, you can write it like this:
mod module {
pub const fiz: u32 = (1 << 0);
pub const foo: u32 = (1 << 1);
pub const bar: u32 = (1 << 2);
pub const baz: u32 = (1 << 3);
}
macro_rules! check_bits {
([$($Constant:expr),*]) => {
|var: u32| {
$(if ($Constant & var) != 0 {
return $Constant;
})*
return 0;
}
}
}
fn main() {
let var = 5;
let checker = check_bits!([module::bar, module::fiz, module::foo, module::baz]);
assert_eq!(checker(var), module::bar);
println!("All OK");
}

Issue with getting 2 chars from string using indexer

I am facing an issue in reading char values.
See my program below. I want to evaluate an infix expression.
As you can see I want to read '10' , '*', '20' and then use them...but if I use string indexer s[0] will be '1' and not '10' and hence I am not able to get the expected result.
Can you guys suggest me something? Code is in c#
class Program
{
static void Main(string[] args)
{
string infix = "10*2+20-20+3";
float result = EvaluateInfix(infix);
Console.WriteLine(result);
Console.ReadKey();
}
public static float EvaluateInfix(string s)
{
Stack<float> operand = new Stack<float>();
Stack<char> operator1 = new Stack<char>();
int len = s.Length;
for (int i = 0; i < len; i++)
{
if (isOperator(s[i])) // I am having an issue here as s[i] gives each character and I want the number 10
operator1.Push(s[i]);
else
{
operand.Push(s[i]);
if (operand.Count == 2)
Compute(operand, operator1);
}
}
return operand.Pop();
}
public static void Compute(Stack<float> operand, Stack<char> operator1)
{
float operand1 = operand.Pop();
float operand2 = operand.Pop();
char op = operator1.Pop();
if (op == '+')
operand.Push(operand1 + operand2);
else
if(op=='-')
operand.Push(operand1 - operand2);
else
if(op=='*')
operand.Push(operand1 * operand2);
else
if(op=='/')
operand.Push(operand1 / operand2);
}
public static bool isOperator(char c)
{
bool result = false;
if (c == '+' || c == '-' || c == '*' || c == '/')
result = true;
return result;
}
}
}
You'll need to split the string - which means working out exactly how you want to split the string. I suspect you'll find Regex.Split to be the most appropriate splitting tool in this case, as you're dealing with patterns. Alternatively, you may want to write your own splitting routine.
Do you only need to deal with integers and operators? How about whitespace? Brackets? Leading negative numbers? Multiplication by negative numbers (e.g. "3*-5")?
Store the numerical value in a variable, and push that when you encounter an operator or the end of the string:
int num = 0;
foreach (char c in s) {
if (isOperator(c)) {
if (num != 0) {
operand.Push(num);
num = 0;
}
operator1.Push(c);
if (operand.Count == 2) {
Compute(operand, operator1);
}
} else {
num = num * 10 + (int)(c - '0');
}
}
if (num != 0) {
operand.Push(num);
}