Попытка выяснить сообщение об ошибке с делением - Haskell - PullRequest
4 голосов
/ 29 января 2020

Я новичок в Haskell и получаю ошибку, пытаясь разделить результат truncate на число. Я не уверен, каковы числовые типы после усечения и почему происходит сбой в моем делении. Спасибо.

-- Create 10^n
tens :: Int -> Integer
tens n = fromIntegral(product (take n [10, 10 .. ]))

-- Rounds list of numbers to n decimal places
rd n x = map (\r -> truncate(r * (tens n)) `div` (tens n)) x

main = do
  -- expected output: [2.12, 3.45, 4.67]
  print (rd 2 [2.123,3.456,4.675])

Сообщение об ошибке:

main.hs:8:21: error:
    • No instance for (RealFrac Integer)
        arising from a use of ‘truncate’
    • In the first argument of ‘div’, namely ‘truncate (r * (tens n))’
      In the expression: truncate (r * (tens n)) `div` (tens n)
      In the first argument of ‘map’, namely
        ‘(\ r -> truncate (r * (tens n)) `div` (tens n))’
  |
8 | rd n x = map (\r -> truncate(r * (tens n)) `div` (tens n)) x
  |                     ^^^^^^^^^^^^^^^^^^^^^^
main.hs:11:16: error:
    • No instance for (Fractional Integer)
        arising from the literal ‘2.123’
    • In the expression: 2.123
      In the second argument of ‘rd’, namely ‘[2.123, 3.456, 4.675]’
      In the first argument of ‘print’, namely
        ‘(rd 2 [2.123, 3.456, 4.675])’
   |
11 |   print (rd 2 [2.123,3.456,4.675])
   |                ^^^^^
<interactive>:3:1: error:
    • Variable not in scope: main
    • Perhaps you meant ‘min’ (imported from Prelude)

1 Ответ

4 голосов
/ 29 января 2020

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

              tens    :: Int  ->                    Integer
              tens (n :: Int) ::                    Integer
          r * tens  n         ::                    Integer
          r                   ::                    Integer
truncate :: (            RealFrac a, Integral b) => a        ->               b
truncate (r * tens  n :: RealFrac Integer        => Integer) :: Integral b => b

, то есть ваш код говорит, что в области видимости должен быть экземпляр RealFrac Integer. Но это не то, о чем говорит сообщение об ошибке.

Обычно мы усекаем числа с плавающей запятой, чтобы получить всю их часть в виде значения типа Integral, но аргумент r * tens n уже является целое число.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...