How to pass method to block in Crystal - crystal-lang

How to pass plus into calculate method?
def calculate(&block : (Float64, Float64) -> Float64)
block.call(1.1, 2.2)
end
def plus(a, b)
a + b
end
calculate{|a, b| plus a, b}
This won't work
calculate ->plus
calculate &plus
P.S.
Another question, how to make it to work for all numbers? Not just Float64. This code won't compile and complain about requiring more specific type than Number
def calculate(&block : (Number, Number) -> Number)
block.call(1, 2)
end
Ideally it would be nice to make it generalised so that typeof(block.call(1, 2)) => Int32 and typeof(block.call(1.1, 2.2)) => Float64

How to pass plus into calculate method?
You're looking for
calculate(&->plus(Float64, Float64))
Where ->plus(Float64, Float64) returns a Proc. Mind that you have to specify the type of the arguments - see the section From methods in the reference manual.
how to make it to work for all numbers?
I'd look into forall - see the section on Free variables in the reference manual.

A generalized solution could work with free variables, but there's a catch because free variables can't be derived from block arguments:
def calculate(&block : (T, T) -> T) forall T # Error: undefined constant T
This is because block arguments can't be overloaded since they can simply be captured blocks without type restrictions.
There are two options to make this work:
You can pass the type for T explicitly as an argument. This is a bit more verbose but works with a captured block argument.
def plus(a, b)
a + b
end
def calculate(t : T.class, &block : (T, T) -> T) forall T
block.call(1.1, 2.2)
end
calculate(Float64, &->plus(Float64, Float64))
You can change the captured block argument to a normal argument receiving a Proc:
def plus(a, b)
a + b
end
def calculate(block : (T, T) -> T) forall T
block.call(1.1, 2.2)
end
calculate(->plus(Float64, Float64))

Related

Is there a way to express the function application operator/function with Hana?

My question
I'm referring to a function which does essentially the following (modulo const, &, perfect forwarding, or whatever is appropriate):
auto constexpr dollar = [](auto f, auto x){ return f(x); }; // Why calling it "dollar"? Keep reading...
Is such a function expressable only via Boost.Hana?
Why did I think of it?
In Haskell, such a function exists, and it's called ($) ($ in infix form), and its definition is the following (source code)
($) :: forall r a (b :: TYPE r). (a -> b) -> a -> b
f $ x = f x
and you could write the second line simply as either of the following
(f $) = f
($) f = f
where the second form makes it apparent that ($) is essentially the same as the id (identity function)
id :: a -> a
id x = x
just with a signature that enforces that the first argument be of function type a -> b and the second argument of type a.
Indeed, applying f to x in Haskell can be done also by writing this
f `id` x
i.e. using `id` instead of $.¹
How is that related to Hana?
Since Hana does offer an id function, I was wondering if that (maybe together with something else) can be used to define a function application utility without manually writing the lambda at the top of this post.
The difficult part
The hard part here is that when you write f `id` x in Haskell, there's not much really a point in arguing on whether you're passing 1 or 2 arguments to id, because all functions are curried by default.
That's not true in C++. For instance I can do this:
#include <boost/hana/functional/id.hpp>
#include <iostream>
using boost::hana::id;
int main() {
auto plus1 = [](int x){ return x + 1; };
std::cout << id(plus1)(3) << std::endl; // prints 4
}
which looks a lot like id is curried and is being given two inputs one after the other rather than together, but that's not true. It's just that id(plus1) is returning plus1, which is fed with 3. I don't know how to get the following (which would be equivalent to plus1 `id` 3 or id plus1 3 in Haskell) work:
std::cout << id(plus1, 3) << std::endl; // doesn't even compile obviously
The true origin of the puzzle
After reading To Mock a Mockingbird, I wondered: "How do I implement the Thrush in C++ only with Boost.Hana?" (And the Thrush is the boost::hana::flipped version of the function application operator.)
¹In reality it's not exactly the same if want to write chains of applications, as the two operators have different associativity, so f $ g $ x == f `id` (g `id` x), but this is not relevant to the question, I believe.

Using a particular higher-order helper function to compute factorial

I'm taking a MOOC (no credit). One of the assigned problems is to write a factorial function using a function that follows this:
(’a->’a)->(’a->bool)->’a->’a
I've created that function:
fun do_until (f, g) = fn x => case g(f x) of
false => f x
| _ => do_until(f,g) (f x);
but I've had difficulty using my do_until function to implement factorial.
The solution should follow this format I believe:
fun factorial x = (do_until (f, g)) x
The problem I see is that the 'g' function can only validate the result, and if validated, then return that result. Since the function type descriptors are fairly restrictive, it limits you from passing in a tuple to g, then verifying off part of the tuple and returning the other part. ie. (factorial, int to mult) then g would verify from #2 and return #1. Unfortunately the types prevent that. I'm starting to think using do_until as a helper function is impossible unless you compute the factorial some other way and then 'g' would just compare your result to that. Please let me know if I'm wrong and where to go next!
You have the wrong type – the function should be curried – and you will probably have more luck if you give the parameters more descriptive names than "f" and "g":
fun do_until next done x = if done x
then x
else do_until next done (next x)
Note that you can pass anything from factorial to do_until – for instance a tuple that holds your computation state – and then "take it apart" once do_until is done. (I suspect that this is why you're stuck.)

What is <cycle> in data?

(I use OCaml version 4.02.3)
I defined a type self
# type self = Self of self;;
type self = Self of self
and its instance s
# let rec s = Self s;;
val s : self = Self <cycle>
Since OCaml is a strict language, I expected defining s will fall into infinite recursion. But the interpreter said s has a value and it is Self <cycle>.
I also applied a function to s.
# let f (s: self) = 1;;
val f : self -> int = <fun>
# f s;;
- : int = 1
It seems s is not evaluated before the function application (like in non-strict language).
How OCaml deal with cyclic data like s? Self <cycle> is a normal form?
OCaml is indeed an eager language, however s is a perfectly valid and fully evaluated term that happens to contain a cycle. For instance, this code yields the expected result:
let f (Self Self x) = x
f s == s;;
More precisely, the memory representation of constructors with at n arguments are boxed and read like this:
⋅—————————————————————————————————————————————⋅
| header | field[0] | field[1] | ⋯ | fiekd[n] |
⋅—————————————————————————————————————————————⋅
The header contains metadata whereas field[k] is an OCaml value, i.e. either an integer or a pointer. In the case of s, Self has only one argument, and thus only one field field[0]. The value of field[0] is then simply a pointer towards the start of the block. The term s is thus perfectly representable in OCaml.
Moreover, the toplevel printer is able to detect this kind of cycles and print an <cycle> to avoid falling into an infinite recursion when printing the value of s. Here, <cycle>, like <abstr> or <fun>, represents just a kind of value that the toplevel printer cannot print.
Note, however, that cyclical value will trigger infinite recursion in many situations, for instance f s = s where (=) is the structural equality
and not the physical one (i.e. (==)) triggers such recursion, another example would be
let rec ones = 1 :: ones;; (* prints [1;<cycle>] *)
let twos = List.map ((+) 1) ones;; (* falls in an infinite recursion *)

Flatten a list of tuples in Scala?

I would have thought that a list of tuples could easily be flattened:
scala> val p = "abcde".toList
p: List[Char] = List(a, b, c, d, e)
scala> val q = "pqrst".toList
q: List[Char] = List(p, q, r, s, t)
scala> val pq = p zip q
pq: List[(Char, Char)] = List((a,p), (b,q), (c,r), (d,s), (e,t))
scala> pq.flatten
But instead, this happens:
<console>:15: error: No implicit view available from (Char, Char) => scala.collection.GenTraversableOnce[B].
pq.flatten
^
I can get the job done with:
scala> (for (x <- pq) yield List(x._1, x._2)).flatten
res1: List[Char] = List(a, p, b, q, c, r, d, s, e, t)
But I'm not understanding the error message. And my alternative solution seems convoluted and inefficient.
What does that error message mean and why can't I simply flatten a List of tuples?
If the implicit conversion can't be found you can supply it explicitly.
pq.flatten {case (a,b) => List(a,b)}
If this is done multiple times throughout the code then you can save some boilerplate by making it implicit.
scala> import scala.language.implicitConversions
import scala.language.implicitConversions
scala> implicit def flatTup[T](t:(T,T)): List[T]= t match {case (a,b)=>List(a,b)}
flatTup: [T](t: (T, T))List[T]
scala> pq.flatten
res179: List[Char] = List(a, p, b, q, c, r, d, s, e, t)
jwvh's answer covers the "coding" solution to your problem perfectly well, so I am not going to go into any more detail about that. The only thing I wanted to add was clarifying why the solution that both you and jwvh found is needed.
As stated in the Scala library, Tuple2 (which (,) translates to) is:
A tuple of 2 elements; the canonical representation of a Product2.
And following up on that:
Product2 is a cartesian product of 2 components.
...which means that Tuple2[T1,T2] represents:
The set of all possible pairs of elements whose components are members of two sets (all elements in T1 and T2 respectively).
A List[T], on the other hand, represents an ordered collections of T elements.
What all this means practically is that there is no absolute way to translate any possible Tuple2[T1,T2] to a List[T], simply because T1 and T2 could be different. For example, take the following tuple:
val tuple = ("hi", 5)
How could such tuple be flattened? Should the 5 be made a String? Or maybe just flatten to a List[Any]? While both of these solutions could be used, they are working around the type system, so they are not encoded in the Tuple API by design.
All this comes down to the fact that there is no default implicit view for this case and you have to supply one yourself, as both jwvh and you already figured out.
We needed to do this recently. Allow me to explain the use case briefly before noting our solution.
Use case
Given a pool of items (which I'll call type T), we want to do an evaluation of each one against all others in the pool. The result of these comparisons is a Set of failed evaluations, which we represent as a tuple of the left item and the right item in said evaluation: (T, T).
Once these evaluations are complete, it becomes useful for us to flatten the Set[(T, T)] into another Set[T] that highlights all the items that have failed any comparisons.
Solution
Our solution for this was a fold:
val flattenedSet =
set.foldLeft(Set[T]())
{ case (acc, (x, y)) => acc + x + y }
This starts with an empty set (the initial parameter to foldLeft) as the accumulator.
Then, for each element in the consumed Set[(T, T)] (named set) here, the fold function is passed:
the last value of the accumulator (acc), and
the (T, T) tuple for that element, which the case deconstructs into x and y.
Our fold function then returns acc + x + y, which returns a set containing all the elements in the accumulator in addition to x and y. That result is passed to the next iteration as the accumulator—thus, it accumulates all the values inside each of the tuples.
Why not Lists?
I appreciated this solution in particular since it avoided creating intermediate Lists while doing the flattening—instead, it directly deconstructs each tuple while building the new Set[T].
We could also have changed our evaluation code to return List[T]s containing the left and right items in each failed evaluation—then flatten would Just Work™. But we thought the tuple more accurately represented what we were going for with the evaluation—specifically one item against another, rather than an open-ended type which could conceivably represent any number of items.

Recursive function that returns all values in list (In OCaml)

I need a function that recursively returns (not prints) all values in a list with each iteration. However, every time I try programming this my function returns a list instead.
let rec elements list = match list with
| [] -> []
| h::t -> h; elements t;;
I need to use each element each time it is returned in another function that I wrote, so I need these elements one at a time, but I can't figure this part out. Any help would be appreciated.
Your function is equivalent to :
let rec elements list =
match list with
| [] -> []
| h :: t -> elements t
This happens because a ; b evaluates a (and discards the result) and then evaluates and returns b. Obviously, this is in turn equivalent to:
let elements (list : 'a list) = []
This is not a very useful function.
Before you try solving this, however, please understand that Objective Caml functions can only return one value. Returning more than one value is impossible.
There are ways to work around this limitation. One solution is to pack all the values you wish to return into a single value: a tuple or a list, usually. So, if you need to return an arbitrary number of elements, you would pack them together into a list and have the calling code process that list:
let my_function () = [ 1 ; 2; 3; 4 ] in (* Return four values *)
List.iter print_int (my_function ()) (* Print four values *)
Another less frequent solution is to provide a function and call it on every result:
let my_function action =
action 1 ;
action 2 ;
action 3 ;
action 4
in
my_function print_int
This is less flexible, but arguably faster, than returning a list : lists can be filtered, sorted, stored...
Your question is kind of confusing - you want a function that returns all the values in a list. Well the easiest way of returning a variable number of values is using a list! Are you perhaps trying to emulate Python generators? OCaml doesn't have anything similar to yield, but instead usually accomplishes the same by "passing" a function to the value (using iter, fold or map).
What you have currently written is equivalent to this in Python:
def elements(list):
if(len(list) == 0):
return []
else:
list[0]
return elements(list[1:])
If you are trying to do this:
def elements(list):
if(len(list) > 0):
yield list[0]
# this part is pretty silly but elements returns a generator
for e in elements(list[1:]):
yield e
for x in elements([1,2,3,4,5]):
dosomething(x)
The equivalent in OCaml would be like this:
List.iter dosomething [1;2;3;4;5]
If you are trying to determine if list a is a subset of list b (as I've gathered from your comments), then you can take advantage of List.mem and List.for_all:
List.for_all (fun x -> List.mem x b) a
fun x -> List.mem x b defines a function that returns true if the value x is equal to any element in (is a member of) b. List.for_all takes a function that returns a bool (in our case, the membership function we just defined) and a list. It applies that function to each element in the list. If that function returns true for every value in the list, then for_all returns true.
So what we have done is: for all elements in a, check if they are a member of b. If you are interested in how to write these functions yourself, then I suggest reading the source of list.ml, which (assuming *nix) is probably located in /usr/local/lib/ocaml or /usr/lib/ocaml.