Комментарии 34
Тема не раскрыта. Где функциональное программирование? Где варианты из ML/хаскел, которые просто таки просятся на место enum в Си и как раз показывают изящество ФЯП, позволяющих выводить тип функции из её аргументов?
+6
data Tea_type = Black|Green deriving Show
data Tea_cup = Tea_cup { sugar ::Bool, _type::Tea_type } deriving Show
drink :: Tea_cup -> String
drink = show
main = putStrLn $ drink $ Tea_cup True Black
data Tea_cup = Tea_cup { sugar ::Bool, _type::Tea_type } deriving Show
drink :: Tea_cup -> String
drink = show
main = putStrLn $ drink $ Tea_cup True Black
+1
ну или вот так:
data Tea_type = Black|Green|Empty deriving Show
data Tea_cup = Tea_cup { sugar ::Bool, _type::Tea_type,water::Bool } deriving Show
addTea Empty x = x
addTea t x@(Tea_cup _ Empty _) = x{ _type=t }
hasSugar = sugar
addSugar x = if hasSugar x then x else x{ sugar=True }
hasWater = water
addWater x = if hasWater x then x else x{ water=True }
newTea_cup = Tea_cup False Empty False
makeTea t = addSugar $ addTea t $ addWater $ newTea_cup
drink x@(Tea_cup _ _ False) = x
drink x = x{sugar=False, _type = Empty, water = False }
main = do
let x = makeTea Black
putStrLn $ show x
putStrLn $ show $ drink x
data Tea_type = Black|Green|Empty deriving Show
data Tea_cup = Tea_cup { sugar ::Bool, _type::Tea_type,water::Bool } deriving Show
addTea Empty x = x
addTea t x@(Tea_cup _ Empty _) = x{ _type=t }
hasSugar = sugar
addSugar x = if hasSugar x then x else x{ sugar=True }
hasWater = water
addWater x = if hasWater x then x else x{ water=True }
newTea_cup = Tea_cup False Empty False
makeTea t = addSugar $ addTea t $ addWater $ newTea_cup
drink x@(Tea_cup _ _ False) = x
drink x = x{sugar=False, _type = Empty, water = False }
main = do
let x = makeTea Black
putStrLn $ show x
putStrLn $ show $ drink x
+1
Чёт я не понял прикол про С++, а почему тип передаем строкой? Что за маразм? Почему бы не передать TeaCup::Type и передавать в виде TeaCup::Black, конечно может показаться, что чёрная кружка, а не чай, но можно и статические константы закинуть, в плане производительности нормальный вариант.
+4
Насчёт PHP
1) Давно уже есть __autoload()
2) set_time_limit(0); было бы смешнее, если
1) Давно уже есть __autoload()
2) set_time_limit(0); было бы смешнее, если
while($cup->drink()) {} // чай можно пить бесконечно
+2
autoload — Вы правы, изобретено давно, и технология хорошая, но не видел, чтобы его сильно активно использовали.
На мой взгляд, всякие require_once(«functions.php») еще слишком живы в среде разного рода разработчиков.
Поэтому, хоть на PHP и можно написать очень круто, с использованием современных возможностей языка, этот пример оставлю как иллюстрацию «так пишут»
На мой взгляд, всякие require_once(«functions.php») еще слишком живы в среде разного рода разработчиков.
Поэтому, хоть на PHP и можно написать очень круто, с использованием современных возможностей языка, этот пример оставлю как иллюстрацию «так пишут»
0
SQL
SELECT `content` FROM `cup` WHERE `drink` = 'black_tea' AND `content` IS NOT NULL LIMIT 1;
+7
Забыли LEFT JOIN sugar :)
0
Скорее UNION, потому что мы же не будем выбирать из сахарницы именно тот сахар, который соответствует нашей чашке чая.
0
НЛО прилетело и опубликовало эту надпись здесь
Видимо объем описывается где-то еще и он является константой.
0
Видимо, давно не пил чай с сахаром, поэтому для меня это булева опция :-)
Но Вы правы, безусловно
Но Вы правы, безусловно
0
class tea_cup:
def tea_cup(self):
self.want = []
наверное вы имели ввиду:
class tea_cup:
def __init__(self):
self.want = []
видимо привычка от C/C++
def tea_cup(self):
self.want = []
наверное вы имели ввиду:
class tea_cup:
def __init__(self):
self.want = []
видимо привычка от C/C++
0
Ваш python какой-то странный. Функция tea_cup видимо по замыслу играет роль конструктора? Вот конструктор класса:
И в качестве небольшого замечания: название класса не соответствует рекомендациям PEP8: TeaCup, и по хорошему, должен наследоваться от object.
def __init__(self): self.want = []
И в качестве небольшого замечания: название класса не соответствует рекомендациям PEP8: TeaCup, и по хорошему, должен наследоваться от object.
+1
как прострелить себе ногу на разных языках программирования. почти везде без кода, зато весело.
+1
Из этого текста я также понял:
Мой вариант для PHP:
- Чашки после себя моют только программисты С++ (и возможно PHP, так как реализация класса от нас скрыта)
- Программисты на Java и С пьют чай без сахара
- Автор всей душой ненавилит PHP, так как хуже код и придумать сложно
Мой вариант для PHP:
<?php
interface Drinkable {
//Это можно пить
public function drink();
}
class Liquid_Exception extends Exception {}
//Абстрактный класс Жидкость
abstract class Liquid {
//Объем жидкости
protected $_amount = null;
public function setAmount($amount) {
$this->_amount = $amount;
return $this;
}
public function getAmount() {
return $this->_amount;
}
}
//Абстрактный класс Кипяченая жидкость
abstract class BoiledLiquid extends Liquid {
//Уже вскипятили???
protected $_isBoiled = false;
//Уже вскипятили???
public function isBoiled() {
return $this->_isBoiled;
}
//Закипятить!
public function boil() {
$this->_isBoiled = true;
return $this;
}
}
//Класс Чай (наследуется от класса Кипяченая жидкость) и его можно пить!
class Tea extends BoiledLiquid implements Drinkable {
//Количество сахара
protected $_sugar = 0;
//Лимончику???
protected $_lemon = false;
/*public function __construct($sugar = 0, $lemon = false) {
$this->boil()->setSugar($sugar)->setLemon($lemon);
}*/
//Насыпать сахарку
public function setSugar($sugar) {
$this->_sugar = $sugar;
return $this;
}
//Сколько сахара?
public function getSugar() {
return $this->_sugar;
}
//Кинуть лимончик
public function setLemon($lemon) {
$this->_lemon = $lemon;
return $this;
}
//А лимончик кинули?
public function getLemon() {
return $this->_lemon;
}
//Пьем чай
public function drink() {
if ($this->getAmount() <=0 ) {
throw new Liquid_Exception('А пить-то нечего!!!');
}
if (!$this->isBoiled()) {
throw new Liquid_Exception('Пить холодный??? Фи!');
}
return array(
'sugar' => $this->getSugar(),
'lemon' => $this->getLemon()
);
}
}
class Cup_Exception extends Exception {}
//Абстрактный класс Чашка
abstract class Cup {
//Вместимость чашки
protected $_capacity = null;
//Содержимое чашки
protected $_liquid = null;
//Наливаем в чашку жидкость
public function fill(Liquid $liquid) {
if ($liquid->getAmount() > $this->getCapacity()) {
throw new Cup_Exception('Куда ты столько льешь? Кто с пола вытирать будет?');
}
$this->_liquid = $liquid;
return $this;
}
//Выливаем жидкость из чашки
public function outpour() {
$liquid = $this->_liquid;
unset($this->_liquid);
return $liquid;
}
//Чашка пустая???
public function isEmpty() {
//Проверяем, что в чашке вообще содержиться жидкость и ее объем больше 0
return (!($this->_liquid instanceOf Liquid) || $this->_liquid->getAmount() > 0);
}
public function setCapacity($capacity) {
$this->_capacity = $capacity;
return $this;
}
public function getCapacity() {
return $this->_capacity;
}
public static function factory($type) {
$className = ucfirst($type) . 'Cup';
if (class_exists($className, true)) {
$reflector = new ReflectionClass($className);
//Это чашка вообще?
if ($reflector->isSubclassOf('Cup')) {
$args = func_get_args();
array_shift($args);
return ($reflector->hasMethod('__construct'))?$reflector->newInstanceArgs($args):$reflector->newInstance();
}
}
return false;
}
//Магический метод для манипуляций с содержимым чашки, не выливая его
public function __call($method, $options) {
if (preg_match('$(set|get)Liquid(\w+)$', $method, $m)) {
$newMethodName = $m[1].$m[2];
if (method_exists($this->_liquid, $newMethodName)) {
return call_user_func_array(array($this->_liquid, $newMethodName), $options);
}
}
throw new Cup_Exception('Такое действие с чашкой выполнять нельзя');
}
}
class CupsShelf_Exception extends Exception {}
//Коллекция чашек на полке
abstract class CupsShelf {
//Сколько всего чашек в доме?
protected static $_totalCupsCount = 0;
//Все чашки, которые есть в доме
protected static $_cups = array();
public static function setTotalCupsCount($totalCupsCount) {
self::$_totalCupsCount = $totalCupsCount;
}
public static function getTotalCupsCount() {
return self::$_totalCupsCount;
}
public static function init() {
if (self::getTotalCupsCount() > 0) {
for($i=0;$i<=self::getTotalCupsCount();$i++){
array_push(self::$_cups, Cup::factory('Tea')->setCapacity(0.25));
}
}
}
public static function getCup() {
for($i=0;$i<=self::getTotalCupsCount();$i++){
$cup = self::$_cups[$i];
if ($cup->isEmpty()) {
return $cup;
}
}
throw new CupsShelf_Exception('Нет свободных чашек');
}
}
//Класс чашка для чая
class TeaCup extends Cup {
}
try {
CupsShelf::setTotalCupsCount(10);
CupsShelf::init();
//Достаем чашку с полки
$cup = CupsShelf::getCup();
//Завариваем чай
$tea = new Tea();
//И закипятить не забыли
$tea->boil()->setAmount(0.25);
//Наливаем в чашку
$cup->fill($tea);
//Кинули в чашку сахарку
$cup->setLiquidSugar(2.5);
//А лимончик мы не любим. Ну его!
$cup->setLiquidLemon(false);
//Пьем!
$cup->outpour()->drink();
}
catch (Exception $e) {
echo 'Да, не пить тебе чаю сегодня... (' . $e->getMessage() . ')';
}
?>
+5
Код тут: gist.github.com/776230
0
Очень развернутый комментарий!
Беглый взгляд показывает, что если убрать "$" и заменить "->" и "::" на ".", то получится неплохой пример на Java
Беглый взгляд показывает, что если убрать "$" и заменить "->" и "::" на ".", то получится неплохой пример на Java
0
На самом деле, Вы вселяете в меня уверенность, что на PHP программируют не только быдлокодеры.
Спасибо Вам за это :-)
Спасибо Вам за это :-)
0
Вот жесть то а! o_O
0
Реквестирую чай на Brainfuck
+1
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
«Чашка чая» на разных языках