Skip to content

Instantly share code, notes, and snippets.

@jacobstanley
Last active March 12, 2016 02:39
Show Gist options
  • Select an option

  • Save jacobstanley/5de10b6ca6482d478f4d to your computer and use it in GitHub Desktop.

Select an option

Save jacobstanley/5de10b6ca6482d478f4d to your computer and use it in GitHub Desktop.
Generic deconstruction of product types to tuples
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE TypeFamilies #-}
module Dissect where
import GHC.Generics
class GDissect f where
type GDissected f
gdissect :: f p -> GDissected f
instance GDissect f => GDissect (M1 i c f) where
type GDissected (M1 i c f) =
GDissected f
gdissect (M1 x) =
gdissect x
instance (GDissect f, GDissect g) => GDissect (f :*: g) where
type GDissected (f :*: g) =
(GDissected f, GDissected g)
gdissect (x :*: y) =
(gdissect x, gdissect y)
instance GDissect (K1 i c) where
type GDissected (K1 i c) =
c
gdissect (K1 x) =
x
--
-- Generic type of Foo:
--
-- M1 D D1Foo
-- (M1 C C1_0Foo
-- (M1 S NoSelector (Rec0 Int) :*:
-- (M1 S NoSelector (Rec0 Int) :*:
-- M1 S NoSelector (Rec0 String))))
--
data Foo = Foo Int Int String
deriving (Generic)
foo :: Foo -> (Int, (Int, String))
foo = gdissect . from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment