简体   繁体   中英

Simple GHC.Generics example

I'm trying to create minimal working example of how to use GHC.Generics, by following the wiki article . Here's what I have:

{-# LANGUAGE DefaultSignatures, DeriveGeneric, TypeOperators, FlexibleContexts #-}

import GHC.Generics

data Bit = O | I deriving Show

class Serialize a where
  put :: a -> [Bit]

  default put :: (Generic a, GSerialize (Rep a)) => a -> [Bit]
  put a = gput (from a)

class GSerialize f where
  gput :: f a -> [Bit]

instance GSerialize U1 where
  gput U1 = []

instance (GSerialize a, GSerialize b) => GSerialize (a :*: b) where
  gput (a :*: b) = gput a ++ gput b

instance (GSerialize a, GSerialize b) => GSerialize (a :+: b) where
  gput (L1 x) = O : gput x
  gput (R1 x) = I : gput x

instance (GSerialize a) => GSerialize (M1 i c a) where
  gput (M1 x) = gput x

instance (Serialize a) => GSerialize (K1 i a) where
  gput (K1 x) = put x


--
-- Try it out...
--

data UserTree a = Node a (UserTree a) (UserTree a) | Leaf
  deriving Generic

instance (Serialize a) => Serialize (UserTree a)

instance Serialize Int


main = do
  print . put $ (Leaf :: UserTree Int)
  print . put $ (Node 7 Leaf Leaf :: UserTree Int)
  print . put $ (3 :: Int)

However, when I try to run this, the program hangs:

λ> main
[I]
[O     -- the program hangs here

What am I doing wrong?

You need a proper instance for Int . That's a built-in type, and you cannot expect magic here. Giving an empty instance for Int will cause the looping (that's arguably a bad design decision, but that's how it currently is).

Here's one that works (but is in no way efficient):

import Data.Bits

boolToBit :: Bool -> Bit
boolToBit False = O
boolToBit True  = I

instance Serialize Int where
  put x = map (boolToBit . testBit x) [0 .. bitSize x - 1]

If you really want a minimal example, then do not use Int , use Tree () or Tree Bool instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM