Как сделать преобразование типов в Haskell? - PullRequest
5 голосов
/ 24 мая 2019

У меня есть следующий код в файле main.hs:

teste :: Integral a => a -> a
teste n = truncate (sqrt n) + mod n 2

и я получаю следующую ошибку от ghci, когда я пытаюсь загрузить его:

Prelude> :l main.hs 
[1 of 1] Compiling Main             ( main.hs, interpreted )

main.hs:12:11:
    Could not deduce (RealFrac a) arising from a use of ‘truncate’
    from the context (Integral a)
      bound by the type signature for teste :: Integral a => a -> a
      at main.hs:11:10-29
    Possible fix:
      add (RealFrac a) to the context of
        the type signature for teste :: Integral a => a -> a
    In the first argument of ‘(+)’, namely ‘truncate (sqrt n)’
    In the expression: truncate (sqrt n) + mod n 2
    In an equation for ‘teste’: teste n = truncate (sqrt n) + mod n 2

main.hs:12:21:
    Could not deduce (Floating a) arising from a use of ‘sqrt’
    from the context (Integral a)
      bound by the type signature for teste :: Integral a => a -> a
      at main.hs:11:10-29
    Possible fix:
      add (Floating a) to the context of
        the type signature for teste :: Integral a => a -> a
    In the first argument of ‘truncate’, namely ‘(sqrt n)’
    In the first argument of ‘(+)’, namely ‘truncate (sqrt n)’
    In the expression: truncate (sqrt n) + mod n 2
Failed, modules loaded: none.

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

Prelude> truncate (sqrt 5) + mod 5 2
3

1 Ответ

6 голосов
/ 24 мая 2019

В вашем звонке truncate (sqrt <b>5</b>) + mod <b>5</b> 2, 5 имеют разные типы.Действительно, 5 в sqrt 5 должно иметь тип Floating a => a, тогда как 5 в mod 5 2 имеет тип Integral b => b.Хотя, строго говоря, возможно построить тип в Haskell, который является членом обоих семейств типов, концептуально нечетно , что тип является одновременно Integral и Floating, это также будет толькоприменимо к таким типам, что делает его менее полезным.Таким образом, мы могли бы изменить подпись на:

teste :: (Integral a, <b>Floating a</b>, <b>RealFrac a</b>) => a -> a
teste n = truncate (sqrt n) + mod n 2

, но, как уже было сказано, это не очень полезно .

Вы можете использовать fromIntegral :: (Integral a, Num b) => a -> b здесь для преобразования из типа Integral в любой тип Num, например:

teste :: Integral a => a -> a
teste n = truncate (sqrt (<b>fromIntegral</b> n)) + mod n 2

Например:

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