25 November, 2016

smuggling things in a dirty bottom

The Haskell unit type, (), has just one value, also written (), right?

smuggle :: Typeable t => t -> ()
discover :: Typeable t => () -> Maybe t

x :: ()
x = smuggle "hello world"

discover x :: Just String
Just "hello world"

These allow you to inject an arbitrary (Typeable) Haskell value into unit and retrieve it later. Just don't try to inspect the resulting () value.

Rather than Haskell 98, you'll need unsafePerformIO and extensible exceptions, put together in a way that lets you hide arbitrary stuff in a thunk, and force evaluation at just the right time.

smuggle :: Typeable t => t -> ()
smuggle v = unsafePerformIO $ throw (toDyn v)

discover :: Typeable t => () -> Maybe t
discover v = either (fromDynamic) (const Nothing)
  $ unsafePerformIO
  $ try
  $ case v of () -> return ()

I could write more. But it's Friday night and I want to drink my wine.

Edit: This is now available on hackage as acme-smuggler.

No comments:

Post a Comment