我遇到了与Haskell类型系统有关的问题。这不是我第一次遇到类型系统的限制。我将省略我的项目详细信息并使用简化示例。这是一些代码:
-- Works
foo :: (Bounded a, Enum a) => a
foo = minBound
-- "ambiguous" constraint:
-- 'a' has no occurrences in type declaration
bar :: (Bounded a, Enum a) => Int
bar = fromEnum minBound
-- Too much information in return
-- but I can show haskell the appropriate type of 'min'
baz :: (Bounded a, Enum a) => (a, Int)
baz = let min = minBound
in (min, someFunction . fromEnum $ min)
-- Type constraint 'a' not ambiguous
-- (or at least that isn't the compiler error message)
-- but Haskell doesn't know which 'minBound' to use
barrer :: (Bounded a, Enum a) => a
barrer = let min = minBound -- <- min's type is ambiguous
in toEnum . someFunction . fromEnum $ min
我想要实现的内容类似于barrer
:首先,使用特定于minBound
类型的a
值并将其“转换”为整数。在我的项目中,我继续转换这个整数(以避免在使用类型a
时出现中间算术溢出)并将它们“强制转换”回a
类型(在mod
魔法之后) 。如何告诉Haskell适当的minBound
类型?有可能吗?
显而易见的解决方案是添加minBound :: a
的注释。这也将修复bar
。问题:类型变量a
似乎超出了函数定义的范围,因为Haskell在错误消息中使minBound :: a
更新为minBound a0
。有没有办法做这种类型的注释?
我使用的一个不好的方法是通过将minBound
调用的类型包含在函数的返回类型la baz
中来限制它的类型。这个解决方案并不理想。有人有建议吗?