Created
September 10, 2012 19:44
-
-
Save ppetr/3693348 to your computer and use it in GitHub Desktop.
An example how to convert any type to any other using Haskell's unsafePerformIO
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module CoerceUsingUnsafe where | |
import Data.IORef | |
import System.IO.Unsafe (unsafePerformIO) | |
import Data.Word | |
{- The trick behind this function is in the `test` experession. | |
When we create a new mutable variable in the IO monad, | |
it has a side effect of creating it somewhere in the memory. | |
If we work within the IO monad, it's all safe. Each time we | |
use an expression containing `newIORef` like `test` a new cell | |
in memory is allocated. | |
However, if we hide this side effect using `unsafePerformIO`, then | |
`test` behaves like a pure expression. If it is evaluated more than | |
once, its value is memoized. So each time we use `test`, we reference | |
the same memory cell it points to. But since `test` is polymorphic, | |
we can view the memory cell as having any type we choose. | |
-} | |
coerce :: a -> b | |
coerce x = unsafePerformIO $ do | |
writeIORef test [x] | |
[y] <- readIORef test | |
return y | |
where | |
test :: IORef [a] | |
test = unsafePerformIO $ newIORef [] | |
main :: IO () | |
main = do | |
-- Int coerced into Word | |
print (coerce (-1 :: Int) :: Word) | |
-- Function coerced into Int | |
print $ (coerce sqrt :: Int) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment