Anonymous user
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,
<lang haskell>main = print $
-- 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 ==
|