Haskell 如何获取具有有界实例的类型的maxBound
以下Haskell代码未编译:Haskell 如何获取具有有界实例的类型的maxBound,haskell,bounded-types,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: getMa
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
我缺少什么?类型签名就足够了
由于签名已经限制了类型,您可以在函数体中删除::a
部分:
getMaxBound :: Bounded a => a -> a
getMaxBound _ = maxBound
使用扩展名
我们还可以使用,然后通过引用a
类型变量来实现:
{-# LANGUAGE ScopedTypeVariables #-}
getMaxBound :: forall a . Bounded a => a -> a
getMaxBound _ = maxBound :: a
{-#语言范围的TypeVariables}
getMaxBound::对于所有a。有界a=>a->a
getMaxBound \=maxBound::a
Willem的答案在这种情况下应该可以正常工作,但在更复杂的情况下,另一种可能也有用的方法是使用-XScopedTypeVariables
如果将行{-#语言作用域TypeVariables#-}
添加到文件的顶部,代码应该可以编译
扩展所做的是允许您从内部范围中的外部范围引用类型变量。在您的代码中,
a
被隐藏在函数体中,并且它与外部a
之间没有连接,导致您丢失限定的a
上下文 正文中的a
是签名中的另一个a
。如何将maxBound
指向签名中的a
?您已经在a->a
签名中完成了。您所需要的一切都是maxBound`asTypeOf`(undefined::Int)
。不需要定义你自己的。谢谢你的回答。有趣!如果我有一个更复杂的函数返回不同的类型,比如说类型b
,那么在Haskell中是否仍然可以表示a
的maxBound
?@MMacphail:如果你将它定义为a->b
,那么这就不起作用了,因为你基本上说“返回值是一个自由选择”而函数体表明它不是。那么上下文重要的函数又是什么呢?rotN::(有界a,枚举a)=>a->a rotN c=toEnum旋转,其中alphabetize=fromnum(maxBound)+1 half alphabet=alphabetizediv
2 offset=fromnum c+half alphabet旋转=offsetmod
alphabetize在本例中,如果我没有指定maxBound的类型,编译器无法决定,但如果我指定a
,编译器会告诉我类型a1
未知。。。当我真的想要签名中的a
时。哈哈,我们(几乎)在同一时间更新:)谢谢,你的两个答案都很好:)我不知道阴影。
{-# LANGUAGE ScopedTypeVariables #-}
getMaxBound :: forall a . Bounded a => a -> a
getMaxBound _ = maxBound :: a