module Issue.TypedValue ( Type (..), cast, castDef, ) where import Data.Maybe (fromMaybe) import Data.Text (Text) import Data.Text qualified as T import Data.Time.Calendar (Day) import Text.Read (readMaybe) data Type a where Date :: Type Day Int :: Type Int String :: Type Text cast :: (forall a. Ord a => a -> a -> b) -> (Text -> Text -> Maybe b) cast eq x y | Just x' <- castTo Date x, Just y' <- castTo Date y = Just (eq x' y') | Just _ <- castTo Date x, Nothing <- castTo Date y = Nothing | Just x' <- castTo Int x, Just y' <- castTo Int y = Just (eq x' y') | Just _ <- castTo Int x, Nothing <- castTo Int y = Nothing | otherwise = Just (eq x y) castDef :: b -> (forall a. Ord a => a -> a -> b) -> (Text -> Text -> b) castDef def eq x y = fromMaybe def (cast eq x y) castTo :: Type a -> Text -> Maybe a castTo Date = readMaybe . T.unpack castTo Int = readMaybe . T.unpack castTo String = Just