Undefined values: Difference between revisions

→‎{{header|Haskell}}: bottom; exceptions
m (→‎{{header|Unix shell}}: corrected section name)
(→‎{{header|Haskell}}: bottom; exceptions)
Line 141:
 
=={{header|Haskell}}==
In Haskell, there is a semantic concept called [http://www.haskell.org/haskellwiki/Bottom "bottom"], which is a computation that never terminates or runs into an error. So <code>undefined</code> is not a proper value at all; it is a bottom that causes an exception when evaluated. For example,
The nullary function <code>undefined</code> returns the undefined value. But Haskell has no way whatsoever to identify or manipulate an undefined value at runtime. In fact, trying to evaluate anything that's undefined terminates the program immediately.
 
<lang haskell>main = print $ 2 + undefined "Incoming error--" An++ error.</lang>undefined
-- When run in GHC:
-- "Incoming error--*** Exception: Prelude.undefined</lang>
 
This isn't quite as dangerous as it sounds because of Haskell's laziness. For example, this program:
Line 155 ⟶ 157:
<lang haskell>resurrect 0 = error "I'm out of orange smoke!"</lang>
 
then if you make the mistake of writing your program such that it at some point requires the value of <code>resurrect 0</code>, you'll get the error message "I'm out of orange smoke!". <code>undefined</code> may be defined in the same way:
 
<lang haskell>undefined :: a
undefined = error "Prelude.undefined"</lang>
 
Since <code>undefined</code> causes an exception, the usual exception handling mechanism can be used to catch it:
 
<lang haskell>import Control.Exception (catch, evaluate, ErrorCall)
import System.IO.Unsafe (unsafePerformIO)
import Prelude hiding (catch)
import Control.DeepSeq (NFData, deepseq)
 
scoopError :: (NFData a) => a -> Either String a
scoopError x = unsafePerformIO $ catch right left
where right = deepseq x $ return $ Right x
left e = return $ Left $ show (e :: ErrorCall)
 
safeHead :: (NFData a) => [a] -> Either String a
safeHead = scoopError . head
 
main = do
print $ safeHead ([] :: String)
print $ safeHead ["str"]</lang>
 
== Icon and Unicon ==
Anonymous user