Show instance for undefined

Is there anything you can do to define a Show instance for undefined? Perhaps there are GHC extensions? I want something like this:

> print (1,undefined)

(1,"undefined")
+3
source share
4 answers

According to the Haskell 2010 report, chapter 9 , evaluation undefinedshould always cause an error:

-- It is expected that compilers will recognize this and insert error
-- messages that are more appropriate to the context in which undefined
-- appears.
undefined :: a
undefined = error "Prelude.undefined"

Since printing a value includes an evaluation, this always leads to an error.

+4
source

( undefined ) - , , , . , . null , .

undefined, error "blah" , . , , .

+2

: "undefined" "X". "X" Char. "undefined"? "undefined" , ( *).

" t" t. , , . "undefined", .

GHCI (), . show , :

Prelude> data Test = Test
Prelude> instance Show Test where show x = "I did not look at x"
Prelude> show Test
"I did not look at x"
Prelude> show (undefined :: Test)
"I did not look at x"

, , undefined, . .

, IO, , :

import Control.Exception
perr s = do x <- try (evaluate (show s)) :: IO (Either SomeException  String)
            return (either show id x))

:

Prelude Control.Exception> perr True
"True"
Prelude Control.Exception> perr (undefined :: Bool)
"Prelude.undefined"

: "perr" WHNF.

+1
source

Although (as others have already pointed out) you cannot specify an instance Showfor undefined, you can build a workaround using catch, as in the following code:

import qualified Control.Exception as C
import System.IO.Unsafe (unsafePerformIO)

showCatch :: (Show a) => a -> IO String
showCatch = showCatch' "undefined"

showCatch' :: (Show a) => String -> a -> IO String
showCatch' undef x = C.catch (C.evaluate (show x)) showUndefined
  where
    showUndefined :: C.ErrorCall -> IO String
    showUndefined _ = return undef

unsafeShowCatch :: (Show a) => a -> String
unsafeShowCatch x = unsafePerformIO (showCatch x)

But this example will only work for simple expressions:

*Main> let v1 = showCatch 1
v1 :: IO String
*Main> let v2 = showCatch $ if True then undefined else 0
v2 :: IO String
*Main> v1
"1"
*Main> v2
"undefined"
*Main> let v3 = unsafeShowCatch 1
v3 :: String
*Main> let v4 = unsafeShowCatch $ undefined
v4 :: String
*Main> v3
"1"
*Main> v4
"undefined"

It will not work for calls like

showCatch (1,undefined)
0
source

All Articles