Haskell:可以在函数定义中使用类型变量吗?

时间:2015-06-02 10:25:48

标签: haskell types

我遇到了与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中来限制它的类型。这个解决方案并不理想。有人有建议吗?

1 个答案:

答案 0 :(得分:14)

ScopedTypeVariables扩展名正好解决了您的问题。该页面还提供了一些替代解决方案(asTypeOfundefined参数)。

相关问题