This fails with dist.sample_dist() is int too nested for type matching. Is there a fix?
{.experimental.}
import std/[random]
randomize()
type
Distribution = concept dist
dist.sample_dist() is int
Die = object
sides: int
func sample_dist( dist: Distribution ) : int =
rand(1..(dist.num_sides))
func roll_dice( d: Die ) : int =
d.sample_dist() + d.sample_dist()
let six_sided = Die(sides: 6)
echo roll_dice six_sided
this works:
import std/[random]
randomize()
type
Distribution = concept dist
dist.num_sides is int
Die = object
num_sides: int
proc sample_dist( dist: Distribution ) : int =
rand(1..(dist.num_sides))
proc roll_dice( d: Die ) : int =
d.sample_dist() + d.sample_dist()
let six_sided = Die(num_sides: 6)
echo roll_dice six_sided
I think the main reason with your snippet is that you are using as a concept constraint (dist.sample_dist is int) something that you cannot check statically without infinite recursion. I think the check happens with the roll_dice call and goes like this:
note that in the snippet above the checks go like this:
here is a variation on the theme:
import std/[random]
randomize()
type
SomeDie = concept d
d.num_sides is int
Die = object
num_sides: int
ColoredDie = object
blue_sides: int
red_sides: int
proc roll(d: SomeDie) : int =
rand(1..(d.num_sides))
proc roll_two(d: SomeDie) : int =
d.roll() + d.roll()
let six_sided = Die(num_sides: 6)
echo roll_two six_sided
func num_sides(d: ColoredDie): int = d.blue_sides + d.red_sides
let color_sided = ColoredDie(blue_sides: 2, red_sides: 7)
echo roll_two color_sided