Есть ли у вас решение в замкнутой форме по индексам, которое соответствует этой функции? Если да, то вы можете использовать Enum
для упрощения. Например,
import Prelude hiding (Either(..))
data Dir = Right
| Front
| Up
| Left
| Back
| Down
deriving (Show, Eq, Ord, Enum)
inv :: Dir -> Dir
inv x = toEnum ((3 + fromEnum x) `mod` 6)
Обратите внимание, что зависит от порядка конструкторов !
*Main> inv Left
Right
*Main> inv Right
Left
*Main> inv Back
Front
*Main> inv Up
Down
Это очень похоже на C, использует упорядочение конструкторов и не является Хаскелли. Компромисс состоит в том, чтобы использовать больше типов , чтобы определить отображение между конструкторами и их зеркалами, избегая использования арифметики.
import Prelude hiding (Either(..))
data Dir = A NormalDir
| B MirrorDir
deriving Show
data NormalDir = Right | Front | Up
deriving (Show, Eq, Ord, Enum)
data MirrorDir = Left | Back | Down
deriving (Show, Eq, Ord, Enum)
inv :: Dir -> Dir
inv (A n) = B (toEnum (fromEnum n))
inv (B n) = A (toEnum (fromEnum n))
Е.Г.
*Main> inv (A Right)
B Left
*Main> inv (B Down)
A Up
Так что, по крайней мере, нам не нужно было заниматься арифметикой. И типы различают зеркальные шкафы. Тем не менее, это очень не Хаскели. Абсолютно хорошо перечислять дела! Другие должны будут прочитать ваш код в какой-то момент ...