packages feed

hid-examples-0.1.0.0: locator.hs

{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE StandaloneDeriving #-}

import Data.List (nub, sort)

class (Enum a, Bounded a) => BoundedEnum a where
  range :: [a]
  range = enumFrom minBound

class (Eq a, Enum a, Bounded a) => CyclicEnum a where
  cpred :: a -> a
  cpred d
    | d == minBound = maxBound
    | otherwise = pred d

  csucc :: a -> a
  csucc d
    | d == maxBound = minBound
    | otherwise = succ d

data Direction = North | East | South | West
  deriving (Eq, Enum, Bounded, CyclicEnum, Show)

--instance CyclicEnum Direction

data Turn = TNone | TLeft | TRight | TAround
  deriving (Eq, Enum, Bounded, BoundedEnum)
           
orient :: Turn -> Direction -> Direction
orient TNone = id
orient TLeft = cpred
orient TRight = csucc
orient TAround = cpred . cpred

findTurn :: Direction -> Direction -> Turn
findTurn d1 d2 = head $ filter (\t -> orient t d1 == d2) range

-- standalone deriving
deriving instance BoundedEnum Direction
deriving instance Ord Turn

test :: Bool
test = sort (nub [ findTurn d1 d2 | d1 <- range, d2 <- range ]) == range

main = do
  putStr "Locator test: "
  print test