Created
May 10, 2016 03:16
-
-
Save ahalbert/f7c56de80d3266c56ceb1f7105de3651 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use v6; | |
unit module Units; | |
class Unit { | |
has Rat $.magnitude; | |
has %.units; | |
multi method mergeUnits(Unit $u) { | |
my %unitm = $u.units; | |
my $op = &[+]; | |
for keys %!units -> $unit { | |
if (%!units{$unit}:exists) { %!units{$unit} = $op(%!units{$unit}, %unitm{$unit}); } | |
else {%!units{$unit} = %unitm{$unit};} | |
} | |
return self.cleanUnits(); | |
} | |
method cleanUnits() { | |
for keys %!units -> $unit { | |
if (%!units{$unit} == 0) {%!units{$unit}:delete;} | |
} | |
} | |
method isSameUnit(Unit $comp) { | |
my %u = $comp.units; | |
if (not %!units == %u) { | |
return False; | |
} | |
for keys %!units -> $u { | |
if (%!units{$u} != %u{$u}) {return False;} | |
} | |
return True; | |
} | |
method gist { | |
my $unitString = ""; | |
my $negUnitString = ""; | |
for kv %!units -> $unit, $exp { | |
if ($exp > 0) {$unitString = $unitString ~ $unit ~ "^" ~ $exp ~ "*";} | |
else {$negUnitString = $unitString ~ $unit ~ "^" ~ (abs $exp) ~ "*";} | |
} | |
$unitString = ($!magnitude.gist) ~ " " ~ $unitString.chop; | |
if ($negUnitString === "") {return $unitString;} | |
return $unitString ~ "/" ~ $negUnitString.chop; | |
} | |
} | |
multi sub infix:<==> (Units::Unit $x, Units::Unit $y) is export { | |
if (not $x.isSameUnit($y)) {die "Units do not match.";} | |
return $x.magnitude == $y.magnitude; | |
} | |
multi sub infix:<===> (Units::Unit $x, Units::Unit $y) is export { | |
return $x.isSameUnit($y) && ($x.magnitude == $y.magnitude); | |
} | |
multi sub infix:<+>(Units::Unit $x, Units::Unit $y) is export { | |
if (not $x.isSameUnit($y)) {die "Units do not match.";} | |
return Unit.new(magnitude => $x.magnitude + $y.magnitude, units => $x.units); | |
} | |
multi sub infix:<->(Units::Unit $x, Units::Unit $y) is export { | |
if (not $x.isSameUnit($y)) {die "Units do not match.";} | |
return Unit.new(magnitude => $x.magnitude - $y.magnitude, units => $x.units); | |
} | |
multi sub infix:<*>(Units::Unit $x, Units::Unit $y) is export { | |
return Unit.new(magnitude => $x.magnitude * $y.magnitude, units => $x.mergeUnits($y.units)); | |
} | |
multi sub infix:</>(Units::Unit $x, Units::Unit $y) is export { | |
return Unit.new(magnitude => $x.magnitude / $y.magnitude, units => $x.mergeUnits(&[-], $y)); | |
} | |
my $a = Units::Unit.new(magnitude => 1.2, units => ("m" => 1)); | |
my $b = Units::Unit.new(magnitude => 5.0, units => ("m" => 1)); | |
my $c = Units::Unit.new(magnitude => 5.0, units => ("m" => 1, "s" => -1)); | |
say $a * $b; | |
# ERROR: | |
# Cannot call AUTOGEN(Units::Unit: Hash); none of these signatures match: | |
# (Units::Unit $: Units::Unit $u, *%_) | |
# Cannot call mergeUnits(Units::Unit: Hash); none of these signatures match: | |
# (Units::Unit $: Units::Unit $u, *%_) | |
# in sub infix:<*> at lib/math/units.pm6 line 65 | |
# in block <unit> at lib/math/units.pm6 line 78 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment