PlusOuMoins/src/Menu.hs

41 lines
1.1 KiB
Haskell

{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Menu (
Menu(..)
, Promptable(..)
, formatTitle
, select
) where
import Control.Monad.IO.Class (MonadIO(..))
import Text.Printf (printf)
import Utils (outputLn, prompt)
data Menu a = Menu {
title :: String
, question :: String
, invalidText :: String
}
formatTitle :: String -> [String]
formatTitle aTitle = [line, formattedTitle, line]
where
formattedTitle = "==> " ++ aTitle
line = const '-' <$> formattedTitle
formatOption :: Promptable a => a -> String
formatOption o = printf "%d. %s" (fromEnum o) (showOption o)
class (Bounded a, Enum a) => Promptable a where
menu :: Menu a
showOption :: a -> String
select :: forall a m. (MonadIO m, Promptable a) => m a
select = toEnum <$> prompt
(mapM_ outputLn (formatTitle title ++ options ++ [question]))
(outputLn invalidText)
(fromEnum (minBound :: a), fromEnum (maxBound :: a))
where
Menu {title, question, invalidText} = (menu :: Menu a)
options = formatOption <$> ([minBound .. maxBound] :: [a])