Function template argument deduction

Paul Backus snarwin at gmail.com
Sat Apr 7 05:10:05 UTC 2018


I'm playing around with functional programming in D, and have run 
into a problem with the following code:

--- list.d
import std.variant: Algebraic, This, visit;
import std.typecons: Tuple, tuple;

struct Nil {}
alias List(T) = Algebraic!(
     Nil,
     Tuple!(T, "head", This*, "tail")
);
alias Cons(T) = Tuple!(T, "head", List!T*, "tail");

List!T* list(T)(T[] items...)
{
     if (items.length == 0)
         return new List!T(Nil());
     else
         return new List!T(Cons!T(items[0], list(items[1..$])));
}

string list2string(T)(List!T list)
{
     import std.stdio: write;

     list.visit!(
         (Nil _) => "nil",
         (Cons!T cons) => "cons(" ~ cons.head ~ ", " ~ 
list2string(*cons.tail) ~ ")"
     );
}


unittest {
     List!int* myList = list(1, 2, 3);

     assert(list2string(*myList) == "cons(1, cons(2, cons(3, 
nil)))");
}

---

The error I get is "template list.list2string cannot deduce 
function from argument types [...]"; i.e., the compiler can't 
figure out that T is supposed to be 'int'.

My question is, why not? Is there anything I can do to get this 
to work? The compiler seems to be able to handle this sort of 
thing in general (e.g., it can deduce 'int' from an argument of 
type 'Tuple!(int, int)'), so what makes this particular case fail?


More information about the Digitalmars-d-learn mailing list