私は次のようなことをしたい:
succ' :: (Bounded a, Eq a, Enum a) => a -> a
succ' n
| n == (maxBound :: a) = minBound :: a
| otherwise = succ n
しかし、これは機能しません。これを解決する方法は?
私は次のようなことをしたい:
succ' :: (Bounded a, Eq a, Enum a) => a -> a
succ' n
| n == (maxBound :: a) = minBound :: a
| otherwise = succ n
しかし、これは機能しません。これを解決する方法は?
いくつかの可能性、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
ここでも必要ありませんが、他の状況で役立つ場合があります。
タイプアノテーションは必要ありません。これらは、発生するエラーの原因です。
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]
た。