Skip to content

Instantly share code, notes, and snippets.

@kana-sama
Created January 25, 2021 15:01
Show Gist options
  • Save kana-sama/c3ef42aac162e5ff4b19044e2b7fd15f to your computer and use it in GitHub Desktop.
Save kana-sama/c3ef42aac162e5ff4b19044e2b7fd15f to your computer and use it in GitHub Desktop.
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
import Unsafe.Coerce
class ToString a where
toString :: a -> String
tag :: String
instance ToString Int where
toString x = "int: " <> show x
tag = "default"
data ToString' a = ToString'
{ toString' :: a -> String,
tag' :: String
}
toStringInt' :: ToString' Int
toStringInt' = ToString' {toString' = \x -> "int: " <> show (x * 10), tag' = "custom"}
newtype Wrapper a b = Wrapper (ToString a => b)
f :: forall a. ToString a => a -> (String, String)
f x = (tag @a, toString x)
f' :: forall a. ToString' a -> a -> (String, String)
f' = unsafeCoerce (Wrapper f :: Wrapper a (a -> (String, String)))
main = do
print $ f (3 :: Int) -- ("default","int: 3")
print $ f' toStringInt' (3 :: Int) -- ("custom","int: 30")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment