A simple example of GHC.Generics

I am trying to create a minimal working example of how to use GHC.Generics, following the wiki article. Here is 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 :: fa -> [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 ica) where gput (M1 x) = gput x instance (Serialize a) => GSerialize (K1 ia) 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 freezes:

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

What am I doing wrong?

+4
source share
1 answer

You need the correct instance for Int . This is a built-in type, and you cannot expect magic here. Providing an empty instance for Int will lead to a loop (this may be a bad design decision, but the way it is now).

Here's the one that works (but by no means effective):

 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 need a minimal example, then do not use Int , use Tree () or Tree Bool instead.

+5
source

Source: https://habr.com/ru/post/1491442/


All Articles