У меня есть пакет, который генерирует код SVG (изображения и значки)
Однако результирующий код svg слишком велик, потому что все числа содержат много знаков после запятой.
Есть ли языковая прагма или что-то подобное, что я могу сделать, чтобы ограничить все числа только 3 десятичными цифрами?
Я хотел бы сделать это с помощью минимального кода, я не хочу применять какую-то функцию к каждому Float
числу индивидуально.
Нет, вы не можете изменить то, как работает арифметика с плавающей запятой IEEE 754. В любом случае, это изменение, вероятно, затронет гораздо больше, чем вы ожидаете. К счастью, вы хотите изменить не то, как представлены числа с плавающей запятой, а то, как они представлены. Таким образом, вам нужно изменить только код, который фактически записывает числа с плавающей запятой в выходной файл, а не весь код, который соприкасается с числами с плавающей запятой.
Вы упоминаете в комментарии, что используете blaze-svg для рендеринга. Было бы полезно включить это в вопрос, поскольку его API влияет на то, что вы можете делать. Я не знаком с этим пакетом, но на первый взгляд он имеет массу функций с подписью
foo :: Show a => a -> Markup
Это довольно неуклюжая подпись, поскольку Show a => a
— это просто странный способ представления строки. Но это означает, что вы не можете просто отформатировать строку самостоятельно, а затем передать ее: вы должны передать что-то, что является Show
. Конечно, String — это Show, но если вы дадите ему String, он вызовет show
для этой String и завершит ее в "
символов! Предположительно, в данный момент вы передаете значения Float, а библиотека их отображает. Вам нужен тип, который действует как Float, но с другой реализацией Show. Вот для чего нужны новые типы:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
newtype ThreeDigitFloat = TDF Float
-- cut any of these you don't need
deriving (Num, Eq, Ord, Floating, RealFloat, Fractional, Real, RealFrac)
instance Show ThreeDigitFloat where
show (TDF x) = _whateverYouWant
Затем вместо работы с Float вы просто работаете с ThreeDigitFloat, и библиотека будет отображать их так, как вы задумали.
Спасибо. Я не уверен, смогу ли я это сделать, потому что рендеринг выполняется пакетом blaze-svg, но я посмотрю на это.
@RamiroPastor Я добавил в ответ раздел о blaze-svg.
Хорошо, я понимаю этот подход, но это то изменение, которого я не хочу, изменение каждого бита кода моего пакета и использование моего собственного типа Float вместо обычного Float, найденного в прелюдии. Тем не менее, помощь очень ценится.
@RamiroPastor Вам нужно будет изменить только подписи типов, а не какую-либо реализацию. Таким образом, компилятор упростит проверку правильности внесения изменений.
Вам нужно будет дать немного больше деталей, чтобы получить конкретный ответ о том, как вы могли бы достичь своей цели. (Только, как ответил Амаллой, глобальная прагма — это не выход.)