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?
JustandNothingare data constructors for the typeMaybe a.IOhas no data constructors to speak of (in GHC it actually has constructors but they're really implementation details of GHC, and other implementations might defineIOdifferently).unwrapIO (IO str) = strdoesn't make sense in the same wayunwrapMaybe (Maybe str) = strdoesn't make sense.IOandMaybeare not data constructors, so you cannot pattern-match on them.