преобразование Num в Fractional в Haskell - PullRequest
0 голосов
/ 12 февраля 2019

В основном у меня есть несколько упражнений для изучения кортежей в Haskell.

В этом я объявляю тип с именем StudentMark, который требует:

  • Строка (имя студента)
  • Int (оценка студента, от 0 до 100).

Затем я должен создать функцию, которая ограничивает оценку студента максимум до 40.

Но я получаю эту ошибку, делая это:

No instance for (Fractional Int) arising from a use of ‘/’

Я думаю, это связано с тем, что я возвращаю double вместо Int, но я не могу понять, как это исправить.Вот код:

import Data.Char

type StudentMark = (String, Int)

{- the total mark without cap would be 100, with the cap it would be 40,
  if we divide 100/40 we get 2.5 which is a common factor
-}
capMark :: StudentMark -> StudentMark
capMark (std, mrk) = (std, fromIntegral (mrk / 2.5))

1 Ответ

0 голосов
/ 12 февраля 2019

Я думаю, это связано с тем, что я возвращаю double вместо Int, но я не могу понять, как это исправить.

Не совсем, в Haskell нет неявногопреобразования.

Поскольку StudentMark фактически является псевдонимом (String, Int), это означает, что mrk является Int.Но ваше деление (/) :: Fractional a => a -> a -> a принимает в качестве типа Fractional a, а Int не является членом класса типов Fractional.Для целочисленных делений можно использовать div :: Integral a => a -> a -> a

Таким образом, мы можем написать это как:

capMark :: StudentMark -> StudentMark
capMark (std, mrk) = (std, <b>div</b> (mrk * 4) <b>10</b>)

или более короткую версию с second :: Arrow a => a b c -> a (d, b) (d, c):

<b>import Control.Arrow(second)</b>

capMark :: StudentMark -> StudentMark
capMark = second ((`div` 10) . (*4))
...