获得有界类型的minBound

dar*_*enn 3 haskell

我一直在尝试做类似的事情:

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似乎没有用.我该怎么办?

chi*_*chi 7

您需要启用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中,每个类型的签名都独立于其他签名.这是aminBound :: 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.

  • 在这种情况下,您是否不能通过删除类型签名来避免扩展?当然,这将很难理解。 (2认同)