Skip to content

Instantly share code, notes, and snippets.

@SamirTalwar
Created January 12, 2022 16:04
Show Gist options
  • Select an option

  • Save SamirTalwar/60399b7f869b1838a1e43959e7a2c332 to your computer and use it in GitHub Desktop.

Select an option

Save SamirTalwar/60399b7f869b1838a1e43959e7a2c332 to your computer and use it in GitHub Desktop.
An example of data families, in preparation for an article.
{-# LANGUAGE NoStarIsType #-}
{-# LANGUAGE TypeFamilies #-}
import Data.Kind (Type)
import Prelude hiding (sum)
class CanSum a where
data Sum a
buildSum :: a -> Sum a
runSum :: Num n => Sum a -> n
sum :: (CanSum a, Num n) => a -> n
sum = runSum . buildSum
instance CanSum Int where
data Sum Int = SumInt Int
buildSum = SumInt
runSum (SumInt x) = fromIntegral x
instance CanSum Integer where
data Sum Integer = SumInteger Integer
buildSum = SumInteger
runSum (SumInteger x) = fromIntegral x
instance (CanSum a, CanSum b) => CanSum (a, b) where
data Sum (a, b) = SumPair (Sum a) (Sum b)
buildSum (x, y) = SumPair (buildSum x) (buildSum y)
runSum (SumPair x y) = runSum x + runSum y
instance (CanSum a) => CanSum [a] where
data Sum [a] = SumList [Sum a]
buildSum xs = SumList (map buildSum xs)
runSum (SumList xs) = foldr (+) 0 $ map runSum xs
{-
sum ((1, 2), ([3, 4, 5], [(6, 7), (8, 9)]))
--> 45
-}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment