Allowing arbitrary types for a function's argument and return type
John Colvin via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Thu Oct 22 07:36:49 PDT 2015
On Thursday, 22 October 2015 at 13:53:33 UTC, pineapple wrote:
> I'm just starting to hammer D's very pleasant syntax into my
> head. After "Hello world", the first thing I do when learning
> any language is to write a simple program which generates and
> outputs the Collatz sequence for an arbitrary number. (I also
> like to golf it.) This is what I wrote in D:
>
> import std.stdio;void main(){int i;readf("
> %d",&i);while(i>1){writeln(i=i%2?i*3+1:i/2);}}
>
> Any ways I could shorten it further?
>
> Anyway, then I thought I should try something that was less of
> a mess, too, and wrote this:
>
> import std.concurrency;
> Generator!int sequence(int i){
> return new Generator!int({
> yield(i);
> while(i > 1){
> yield(i = (i % 2) ? (i * 3 + 1) : (i >> 1));
> }
> });
> }
>
> Which can be used like so:
>
> import std.stdio;
> void main(){
> foreach(i; sequence(11)){
> writeln(i);
> }
> }
>
> And now I'd like to make one more improvement, but this I
> haven't been able to figure out. What if I wanted the argument
> and output types to be longs instead of ints? Or some other,
> arbitrary discrete numeric type? Is there any template-like
> syntax I can use here instead of just copypasting for each
> numeric type I can think of? I've been spoiled by the likes of
> Python to be thinking in this duck-typing way.
>
> Thanks!
Using ranges instead of threads or fibers, slightly
over-engineered to show off features:
import std.traits : isIntegral;
auto collatzStep(T)(T i)
if(isIntegral!T)
{
return (i % 2) ? (i * 3 + 1) : (i >> 1);
}
auto collatz(T)(T a)
if(isIntegral!T)
{
import std.range : recurrence;
import std.algorithm : until, OpenRight;
return a.recurrence!((a, n) => collatzStep(a[n-1]))
.until!(n => n == 1)(OpenRight.no);
}
unittest
{
import std.algorithm : equal;
import std.range : only;
assert(collatz(6L).equal(only(6, 3, 10, 5, 16, 8, 4, 2, 1)));
}
More information about the Digitalmars-d-learn
mailing list