Last active
February 15, 2019 01:33
-
-
Save kkismd/45b3a66194a839e62db4ff2a31add10b 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
<?php | |
declare(strict_types=1); | |
interface Monoid | |
{ | |
public function canBeInstance($a): bool; | |
public function append($a1, $a2); | |
public function zero(); | |
} | |
class StringMonoid implements Monoid | |
{ | |
public function canBeInstance($a): bool | |
{ | |
return is_string($a); | |
} | |
public function append($a1, $a2) | |
{ | |
return $a1 . $a2; | |
} | |
public function zero() | |
{ | |
return ""; | |
} | |
} | |
class IntAddMonoid implements Monoid | |
{ | |
public function canBeInstance($a): bool | |
{ | |
return is_int($a); | |
} | |
public function append($a1, $a2) | |
{ | |
return $a1 + $a2; | |
} | |
public function zero() | |
{ | |
return 0; | |
} | |
} | |
class IntMultiplyMonoid implements Monoid | |
{ | |
public function canBeInstance($a): bool | |
{ | |
return is_int($a); | |
} | |
public function append($a1, $a2) | |
{ | |
return $a1 * $a2; | |
} | |
public function zero() | |
{ | |
return 1; | |
} | |
} | |
class ArrayMonoid implements Monoid | |
{ | |
public function canBeInstance($a): bool | |
{ | |
return is_array($a); | |
} | |
public function append($a1, $a2) | |
{ | |
return array_merge($a1, $a2); | |
} | |
public function zero() | |
{ | |
return array(); | |
} | |
} | |
class MonoidOps | |
{ | |
public function __construct(Monoid ...$instances) | |
{ | |
$this->instances = $instances; | |
} | |
private function getInstance($a) | |
{ | |
foreach ($this->instances as $instance) { | |
if ($instance->canBeInstance($a)) { | |
return $instance; | |
} | |
} | |
throw new LogicException('型クラスインスタンスが見つかりませんでした'); | |
} | |
public function append($a1, $a2) | |
{ | |
$instance = $this->getInstance($a1); | |
return $instance->append($a1, $a2); | |
} | |
public function zero() | |
{ | |
// XXX: どうやってインスタンスを特定する??? | |
} | |
} | |
$monoid = new MonoidOps( | |
new StringMonoid(), | |
new IntAddMonoid(), | |
new ArrayMonoid() | |
); | |
echo $monoid->append('foo', 'bar'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
まずはインスタンスを直接渡す形を考えてみる