Skip to content

Instantly share code, notes, and snippets.

@pjrt
Last active July 26, 2018 08:55
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pjrt/3b2231e323f5a557ebea to your computer and use it in GitHub Desktop.
Save pjrt/3b2231e323f5a557ebea to your computer and use it in GitHub Desktop.
A Typeclass Box in Haskell. Allows for a single type to represent any type that responds to a typeclass.
{-# LANGUAGE GADTs, ConstraintKinds, FlexibleInstances, RankNTypes #-}
-- Our typeclass with a simple foo :: a -> String func
class Foo a where
foo :: a -> String
-- Our test data types and their instances of Foo
data MyFoo = MyFoo String
data MyBar = MyBar Int
instance Foo MyFoo where
foo (MyFoo s) = s
instance Foo MyBar where
foo (MyBar i) = show i
-- Our Typeclass Box (TBox). Needs GADTs. `a` is existential. `c` is a contraint
data TBox c where
TBox :: c a => a -> TBox c
-- A TBox can be represented as a Foo (it is whatever its inner representation of Foo is).
-- Notice that `a` is existential. We don't know what it is, we just know that we can call `foo` on it.
-- Needs FlexibleInstances.
instance Foo (TBox Foo) where
foo (TBox a) = foo a
main = do
-- We can now make a list of TBox where each inner type is different
let listOfFoo = (TBox (MyFoo "hello") : TBox (MyBar 123) : []) :: [TBox Foo]
-- AND we can call `foo` on all of them via map
mapM_ putStrLn $ fmap foo listOfFoo
@pjrt
Copy link
Author

pjrt commented Aug 27, 2014

When compared to this gist, it is interesting to see how little you need to do in Haskell to get the same done. This is mostly due to the fact that type-classes are part of Haskell, as opposed to Scala where they are just a trick that you can do with implicits. Additionally, Scala's syntax is very verbose when compared to Haskell's.

@pjrt
Copy link
Author

pjrt commented Apr 23, 2015

Generalized TBox added. Pretty cool stuff.

@Globidev
Copy link

Globidev commented Jul 2, 2018

Thank you for this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment