我一直在尝试做类似的事情:
f :: (Enum a, Bounded a) => A a b -> [(a,b)]
f x = [(as,bs) | as <- [minBound :: a ..] , bs <- x somefunction as]
Run Code Online (Sandbox Code Playgroud)
但那里的minbound似乎没有用.我该怎么办?
您需要启用ScopedTypeVariables扩展并使用显式foralls:
{-# ScopedTypeVariables #-}
f :: forall a b . (Enum a, Bounded a) => A a b -> [(a,b)]
f x = [(as,bs) | as <- [minBound :: a ..] , bs <- x somefunction as]
Run Code Online (Sandbox Code Playgroud)
如果没有这个,在Haskell中,每个类型的签名都独立于其他签名.这是a在minBound :: a没有任何与a在签名上面.
如果你真的想坚持没有扩展,你可以编写一个辅助功能:
myBound :: Bounded a => A a b -> a
myBound x = minBound -- does not really depend on x
f :: (Enum a, Bounded a) => A a b -> [(a,b)]
f x = [(as,bs) | as <- [myBound x ..] , bs <- x somefunction as]
Run Code Online (Sandbox Code Playgroud)
在这个特定情况下,正如@dfeuer在下面指出的那样,有一个更简单的解决方案.我们可以简单地删除类型注释minBound:
-- no extensions
f :: (Enum a, Bounded a) => A a b -> [(a,b)]
f x = [(as,bs) | as <- [minBound ..] , bs <- x somefunction as]
Run Code Online (Sandbox Code Playgroud)
这是因为列表推导输出对(as,bs),所以Haskell可以看到as必须具有类型a,并且minBound必须是相同类型的as.