1

私は次のようなことをしたい:

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

しかし、これは機能しません。これを解決する方法は?

4

2 に答える 2

7

いくつかの可能性、Haskell2010の方法、

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

タイプは、使用法と両方のタイプから決定され、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

しかし、上で見たように、ここではその必要はありません。

3番目の可能性は、を使用すること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

ここでも必要ありませんが、他の状況で役立つ場合があります。

于 2012-11-14T21:50:07.583 に答える
6

タイプアノテーションは必要ありません。これらは、発生するエラーの原因です。

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

(これはHaskell98とHaskell2010で動作するので、ほとんどすべてのコンパイラーが横になっています。)また、|関数の開始と一致しないため、少しインデントしました。succ'これらは、スタンドアロンコードではなく、の定義の一部です。

ここにいくつかのテストデータがあります:

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

test = map succ' [A .. C]

私は得[B,C,A]た。

于 2012-11-14T21:49:21.127 に答える