Obviously, the following function is impossible, because it is impossible to unwrap an IO value permanently (ignoring unsafePerformIO or similar):
unwrapIO :: IO String -> String
unwrapIO (IO str) = str
However, similar functions such as the following are possible:
unwrapJust :: Maybe String -> String
unwrapJust (Just str) = str
unwrapJust Nothing = "ignore this plz"
I fully understand the reasoning behind why #2 is possible but #1 is not, but I do not understand how. Can I also make my own types that are not unwrappable?
Just
andNothing
are data constructors for the typeMaybe a
.IO
has no data constructors to speak of (in GHC it actually has constructors but they're really implementation details of GHC, and other implementations might defineIO
differently).unwrapIO (IO str) = str
doesn't make sense in the same wayunwrapMaybe (Maybe str) = str
doesn't make sense.IO
andMaybe
are not data constructors, so you cannot pattern-match on them.