如何获取具有Bounded实例的类型的maxBound

时间:2019-01-19 11:18:57

标签: haskell bounded-types

以下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。

我想念什么?

2 个答案:

答案 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