Last active
August 10, 2021 21:42
-
-
Save ndmitchell/a4f2edcedd2d4398efea4755b5d2408f to your computer and use it in GitHub Desktop.
Binary existentials
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
{-# LANGUAGE StaticPointers #-} | |
{-# LANGUAGE InstanceSigs #-} | |
{-# LANGUAGE ExistentialQuantification #-} | |
{-# LANGUAGE ScopedTypeVariables #-} | |
{-# LANGUAGE FlexibleInstances #-} | |
import Data.Binary | |
import System.IO.Unsafe | |
import GHC.StaticPtr | |
data Foo = forall a . (StaticFoo a, Binary a, Show a) => Foo a | |
class StaticFoo a where | |
staticFoo :: a -> StaticPtr (Get Foo) | |
instance StaticFoo String where | |
staticFoo _ = static (Foo <$> (get :: Get String)) | |
instance StaticFoo Int where | |
staticFoo _ = static (Foo <$> (get :: Get Int)) | |
main = do | |
let a = encode $ Foo ("test" :: String) | |
let b = encode $ Foo (123456 :: Int) | |
let f s = case decode s of Foo x -> print x | |
f a | |
f b | |
instance Binary Foo where | |
put :: Foo -> Put | |
put (Foo x) = do | |
put $ staticKey $ staticFoo x | |
put x | |
get :: Get Foo | |
get = do | |
ptr <- get | |
case unsafePerformIO (unsafeLookupStaticPtr ptr) of | |
Just value -> deRefStaticPtr value :: Get Foo | |
Nothing -> error "Binary Foo: unknown static pointer" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment