I'd like a function that takes an argument and gives back a Maybe
value. If the argument has type Maybe a
, the implementation should be id
, and if the argument is anything else, the implementation should be Just
. Surely the right way to do this is with a typeclass, but I'm struggling to get it right. Any suggestions?
main :: IO ()
main = do
print $ toMaybe 3 -- should be `Just 3`
print $ toMaybe (Just 3) -- should be `Just 3` also
I feel like this is probably trivial if I know the right language pragmas or something, but I don't.
You'll need TypeFamilies
, and will probably want DerivingVia
+StandaloneDeriving
+UndecidableInstances
.
class Wrap a where
type Wrapped a
wrap :: a -> Wrapped a
instance Wrap (Maybe a) where
type Wrapped (Maybe a) = Maybe a
wrap = id
-- choice 1: only TypeFamilies
instance Wrap Int where
type Wrapped Int = Maybe Int
wrap = Just
instance Wrap Bool where
type Wrapped Bool = Maybe Bool
wrap = Just
instance Wrapped () where
type Wrapped () = Maybe ()
wrap = Just
-- etc. etc.
-- choice 2: we love extensions, turn them all on why not
newtype UseJust a = UseJust a
instance Wrap (UseJust a) where
type Wrapped (UseJust a) = Maybe a
wrap (UseJust a) = Just a
deriving via UseJust Int instance Wrap Int
deriving via UseJust Bool instance Wrap Bool
deriving via UseJust () instance Wrap ()
-- etc. etc.
And I'll just add a slight warning: to me, this smells. Are you sure you aren't just looking for the Monad
(well, Functor
) instance for Maybe
? If not, are you double-plus sure that two layers of Maybe
really isn't conceptually the right thing to return when presented with a single layer of Maybe
?