如何在Haskell中进行类型转换?

时间:2019-05-24 14:09:52

标签: haskell type-conversion

我在文件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 个答案:

答案 0 :(得分:6)

在您的通话truncate (sqrt 5) + mod 5 2中,5的类型不同。实际上,{{1}中的5应该具有类型sqrt 5,而Floating a => a中的5具有类型mod 5 2。尽管严格说来,可以在Haskell中构造属于两个类型族的成员的类型,但是从概念上说,类型既是Integral b => b也是Integral,它也仅适用于此类类型,从而使其用处不大。因此,我们可以将签名更改为:

Floating

但是如前所述,这不是非常有用。

您可以在此处使用fromIntegral :: (Integral a, Num b) => a -> bteste :: (Integral a, Floating a, RealFrac a) => a -> a teste n = truncate (sqrt n) + mod n 2类型转换为任何Integral类型,例如:

Num

例如:

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