Перевод, “почему вопросы функционального программирования” в Haskell

Обычно я бы сказал (1). Но если вы обнаружите, что все вызывающие объекты окружают конструкцию с помощью try / catch, вы можете также предоставить статическую вспомогательную функцию в (3), так как с небольшой подготовкой исключение может быть сделано невозможным.

Существует еще один вариант, хотя он имеет существенные последствия для стиля кодирования, поэтому его не следует воспринимать легкомысленно,

5) Не передавайте параметры в конструктор:

class Time
{
protected:
    unsigned int m_hour;
    unsigned int m_minute;
    unsigned int m_second;
public:
    Time() : m_hour(0), m_minute(0), m_second(0) {}
    // either return success/failure, or return void but throw on error,
    // depending on why the exception in constructor was undesirable.
    bool Set(unsigned int hour, unsigned int minute, unsigned int second);
};

Это называется двухфазным построением и используется именно в ситуациях, когда конструкторам нежелательно или невозможно генерировать исключения. Код с использованием nothrow new, который должен быть скомпилирован с помощью -fno-exceptions, вероятно, является классическим случаем Как только вы привыкаете к этому, это немного менее раздражает, чем вы могли подумать.

14
задан Andrew Jaffe 17 June 2009 в 11:05
поделиться

3 ответа

4.1 Квадратные корни Ньютона-Рафсона

Эти две строки

sqroot a0 eps n = within eps (iterate (next n) a0)
relativesqrt a0 eps n = relative eps (iterate (next n) a0)

почти идентичны, поэтому вы можете абстрагироваться на один шаг дальше:

sqroot method a0 eps n = method eps (iterate (next n) a0)
relativesqrt = sqroot relative
withinsqrt   = sqroot within

4.2 Числовое дифференцирование

Я не делаю ' Я вижу смысл использования h0 в качестве аргумента функции дифференцирования , поскольку это всего лишь отправная точка для предельной последовательности 0 . (То же самое не верно для a0 в случае Ньютона-Рапсона, где начальная точка может иметь значение.)

Я думаю, также уместно абстрагироваться от скорости, с которой этот предел приближается к нулю:

differentiate rate f x = map (easydiff f x) (iterate rate 1)

Конечно, можно сделать и то, и другое:

differentiate rate h0 f x = map (easydiff f x) (iterate rate h0)

В любом случае это довольно произвольное решение.

4.2 Интеграция

Вы можете использовать

zipWith (+) (integ f a m fa fm) (integ f m b fm fb)

вместо

map (uncurry (+)) (zip (integ f a m fa fm) (integ f m b fm fb))

, что, на мой взгляд, более читабельно.

1111035]

10
ответ дан 1 December 2019 в 13:59
поделиться

Для в и родственник Я бы использовал защищенную нотацию:

within eps (a:b:rest)
  | abs(a-b)<=eps = b
  | otherwise = within eps (b:rest)

Для секунды вы можете написать !! 1 . Я полагаю, что последний вариант - это личное предпочтение.

Вы также должны указать сигнатуры типа.

Изменить : Если вы используете обфускацию, попробуйте:

within :: (Ord a, Num a) => a -> [a] -> a
within eps l@(_:xs) = snd. head . filter ((<= eps) . fst) $ zip zs xs
   where
    zs = zipWith (\ a b -> abs (a-b)) l xs

(Тип проверен, не проверено - и Я никогда не знаю, правильно ли я установил фильтр или его нужно отключить;)

4
ответ дан 1 December 2019 в 13:59
поделиться

Итак, это прямой перевод (т. Е. Старайтесь, чтобы код выглядел как можно более похожим) или встроенный (т. Е. Внесение в код как можно большего количества идиоматических настроек, не усложняя понимание примеров , конечно) один?

Предполагая, что этот "проект" все еще продолжается ......

0
ответ дан 1 December 2019 в 13:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: