Я получаю странные результаты из таблицы, из которой выбираю. Рассмотрим следующую таблицу:
USERID TICKETSASSIGNED
1 0
100 0
101 0
102 0
103 0
Теперь, если у меня есть следующий sql, например:
SELECT TOP 1 USERID
FROM TABLEX
ORDER BY TICKETSASSIGNED
Результат, который я ожидал бы получить, будет «1», но чаще всего я получаю «100», вторую запись. Поскольку TICKETSASSIGNED
все значения равны " Однако меня в основном интересует, как избежать использования такого количества "fromIntegrals".)
Спасибо, Эш
Иногда я считаю полезной вспомогательную функцию:
roundDouble x acc = (round $ x * 10 ^ acc) /. (10 ^ acc)
where
x /. y = fromIntegral x / fromIntegral y
Эту вспомогательную функцию также можно записать:
(/.) = (/) `on` fromIntegral
Где на
взято из Data.Function
.
У меня аналогичная проблема с кодом маршалинга, где fromIntegral
используется для преобразования CInt в Int. Я обычно определяю fI = fromIntegral
, чтобы упростить задачу. Вам также может потребоваться указать явную сигнатуру типа или использовать -XNoMonomorphismRestriction.
Если вы много занимаетесь математикой, вы можете взглянуть на Numeric Prelude , который, кажется, имеет гораздо более разумные отношения между различными числовыми типами.
Вы можете использовать ^
вместо **
. ^
принимает любой Integral в качестве второго аргумента, поэтому вам не нужно вызывать fromIntegral
для второго операнда. Таким образом, ваш код выглядит следующим образом:
roundDouble x acc = fromIntegral (round $ x * 10 ^ acc) / 10 ^ acc
Который имеет только один fromIntegral
. И от этого вы не можете избавиться, поскольку round
естественным образом возвращает Integral, и вы не можете выполнять нецелочисленное деление на Integral.
Еще одна идея, похожая на Луки . Большинство моих проблем с fromIntegral
связаны с необходимостью разделить Int
на Double
или Double
на Int
. Итак, этот (/.)
позволяет разделить любые два вещественных
типа, не обязательно одинаковые, не обязательно интегральные
типа, как в решении Луки:
(/.) :: (Real a, Real b, Fractional c) => a -> b -> c
(/.) x y = fromRational $ (toRational x) / (toRational y)
Пример:
ghci> let (a,b,c) = (2::Int, 3::Double, 5::Int)
ghci> (b/.a, c/.a, a/.c)
(1.5,2.5,0.4)
Он работает для любых двух Real
s, но я подозреваю, что рациональное разделение и преобразование в / из Rational
не очень эффективны.
Теперь ваш пример выглядит следующим образом:
roundDouble :: Double -> Int -> Double
roundDouble x acc = (round $ x * 10 ^ acc) /. (10 ^ acc)