以下Haskell代码无法编译:
getMaxBound :: (Bounded a) => a -> a
getMaxBound _ = maxBound :: a
我得到的错误如下:
Could not deduce (Bounded a1) arising from a use of ‘maxBound’
from the context: Bounded a
bound by the type signature for:
getMaxBound :: Bounded a => a -> a
at rot13.hs:3:1-36
为什么我不能在Haskell中获得有界类型的maxBound?
理想情况下,我会像这样使用此功能:
getMaxBound 3
> 9223372036854775807
getMaxBound 'c'
> '\1114111'
我觉得每当我有一个具有绑定实例的a
类型时,我都应该能够获得该类型的maxBound。
我想念什么?
答案 0 :(得分:4)
在这种情况下,威廉姆(Willem)的回答应该很好,但是在更复杂的情况下也可能有用的替代方法是使用-XScopedTypeVariables
如果将{-# LANGUAGE ScopedTypeVariables #-}
行添加到文件顶部,则应编译代码。
扩展名的作用是允许您从内部作用域中的外部作用域引用类型变量。在您的代码中,a
在函数主体中被遮盖,并且它与外部a
之间没有任何连接,从而导致您失去Bounded a
上下文!
答案 1 :(得分:3)
由于签名已经限制了类型,因此可以将:: a
部分放在函数主体中:
getMaxBound :: Bounded a => a -> a
getMaxBound _ = maxBound
类型签名指定函数输入的类型与函数输出的类型相同。
例如:
Prelude> getMaxBound (3 :: Int)
9223372036854775807
Prelude> getMaxBound 'c'
'\1114111'
Prelude> getMaxBound True
True
Prelude> getMaxBound LT
GT
ScopedTypeVariables
扩展名我们还可以使用ScopedTypeVariables
extension [Haskell-wiki],然后通过引用a
类型变量来实现它:
{-# LANGUAGE ScopedTypeVariables #-}
getMaxBound :: forall a . Bounded a => a -> a
getMaxBound _ = maxBound :: a