Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

Owner

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

This comment has been minimized.

Owner

pjrt commented Apr 23, 2015

Generalized TBox added. Pretty cool stuff.

@Globidev

This comment has been minimized.

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