use v6-alpha; class Unit { has $.q is rw; method set ($self: Num $value) { $.q = $value; $self; }; multi method string ($self:) {$self.q ~ $self.abbreviation; } multi method string ($self: Num $prec) { return $self.q.fmt('%.' ~ $prec ~ 'f') ~ $self.abbreviation; } method toBase($self:) { $.q * $self.baseFactor } method fromBase($self:) { $.q / $self.baseFactor } method setFromBase($self: Num $value) { $.q = $value / $self.baseFactor; } method baseFactor() { 1; } } multi sub *infix:<+> (Unit $a, Unit $b) { die unless $a.type eq $b.type; my $new = $a.clone(); # wierd hack around a wierd error. my $aVal = $a.toBase(); my $bVal = $b.toBase(); $new.setFromBase( $aVal + $bVal); return $new; } multi sub *infix:<-> (Unit $a, Unit $b) { my $new = $a.clone(); # wierd hack around a wierd error. my $aVal = $a.toBase(); my $bVal = $b.toBase(); $new.setFromBase( $aVal - $bVal); return $new; } class Distance is Unit { method type () { 'distance'} } multi sub postfix: (Num $value) { Feet.new().set($value) } class Feet is Distance { method abbreviation () { "ft" }; method baseFactor () { 0.3048 }; } # not m, as that's taken by m// multi sub postfix: (Num $value) { Meter.new().set($value) } class Meter is Distance { method abbreviation () { "m" }; # no base factor because it IS the base Unit } multi sub postfix: (Num $value) { Kilometer.new().set($value) } class Kilometer is Distance { method abbreviation () { "km" }; method baseFactor () { 1000 }; } multi sub prefix:<~> (Unit $unit) { $unit.string; } #multi sub infix:<`> (Int $value, Unit $unit) { $unit.set($value); }; my $feet = 5ft; my $meter = 6m; say $feet.string(); say $meter.string(); # my $z = $x.to($y); # say $z.string; my $add = $feet + $meter; say $add.string(2); my $add2 = $meter + $feet; say ~$add2; my $sub = $meter - $feet; say ~$sub; my $kilometer = 1000km; $add = $kilometer + 90ft; say $add.string(2); my $add = 1ft + 1m; say $add.string(2);