Haskell:泛型函数中的bound-value

Vek*_*weg 1 haskell

我想做点什么:

succ' :: (Bounded a, Eq a, Enum a) => a -> a
succ' n
| n == (maxBound :: a) = minBound :: a
| otherwise = succ n
Run Code Online (Sandbox Code Playgroud)

但这不起作用.怎么解决这个?

Dan*_*her 7

几种可能性,Haskell2010方式,

succ' :: (Bounded a, Eq a, Enum a) => a -> a
succ' n
  | n == maxBound = minBound
  | otherwise = succ n
Run Code Online (Sandbox Code Playgroud)

类型是根据用途,两者的类型确定的,maxBound并且minBound必须是参数的类型.

或者您可以使用ScopedTypeVariables扩展,将类型变量放入范围,以便可以在本地类型签名中使用,

{-# LANGUAGE ScopedTypeVariables #-}

succ' :: forall a. (Bounded a, Eq a, Enum a) => a -> a
succ' n
  | n == (maxBound :: a) = minBound :: a
  | otherwise = succ n
Run Code Online (Sandbox Code Playgroud)

但是,如上所述,这里没有必要.

第三种可能性是使用asTypeOf :: a -> a -> a,

succ' :: (Bounded a, Eq a, Enum a) => a -> a
succ' n
  | n == (maxBound `asTypeOf` n) = minBound `asTypeOf` n
  | otherwise                    = succ n
Run Code Online (Sandbox Code Playgroud)

这里不再需要,但在其他情况下可能有用.


And*_*ewC 6

您不需要类型注释,它们是您获得的错误的来源:

succ' :: (Bounded a, Eq a, Enum a) => a -> a
succ' n
 | n == maxBound = minBound
 | otherwise = succ n
Run Code Online (Sandbox Code Playgroud)

(这适用于Haskell 98和Haskell 2010,所以几乎所有编译器都存在.)另外,我缩进|了一点,因为它们无法与函数的开头对齐; 它们是定义的一部分succ',而不是独立代码.

这是一些测试数据:

data Test = A | B | C 
   deriving (Bounded, Eq, Enum, Show)

test = map succ' [A .. C]
Run Code Online (Sandbox Code Playgroud)

我有[B,C,A].