Haskell:泛型函数中的bound-value

时间:2012-11-14 21:44:52

标签: haskell

我想做类似的事情:

succ' :: (Bounded a, Eq a, Enum a) => a -> a
succ' n
| n == (maxBound :: a) = minBound :: a
| otherwise = succ n

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

2 个答案:

答案 0 :(得分:7)

几种可能性,Haskell2010方式,

succ' :: (Bounded a, Eq a, Enum a) => a -> a
succ' n
  | n == maxBound = minBound
  | otherwise = succ n

类型由使用决定,两者的类型,maxBoundminBound必须是参数的类型。

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

{-# LANGUAGE ScopedTypeVariables #-}

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

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

第三种可能性是使用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

这里也不需要,但在其他情况下也很有用。

答案 1 :(得分:6)

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

succ' :: (Bounded a, Eq a, Enum a) => a -> a
succ' n
 | n == maxBound = minBound
 | otherwise = succ n

(这适用于Haskell 98和Haskell 2010,所以你可以使用任何编译器。) 另外,我稍微缩进|,因为它们无法与函数的开头对齐;它们是succ'定义的一部分,而不是独立代码。

以下是一些测试数据:

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

test = map succ' [A .. C]

我得到[B,C,A]