【问题标题】:Simple GHC.Generics example简单的 GHC.Generics 示例
【发布时间】:2013-07-15 13:57:01
【问题描述】:

我正在尝试通过遵循wiki article 创建如何使用 GHC.Generics 的最小工作示例。这是我所拥有的:

{-# 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)

但是,当我尝试运行它时,程序挂起:

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

我做错了什么?

【问题讨论】:

    标签: generics haskell


    【解决方案1】:

    您需要一个合适的 Int 实例。这是一个内置类型,你不能指望这里有魔法。为 Int 提供一个空实例将导致循环(可以说这是一个糟糕的设计决策,但目前就是这样)。

    这是一个有效的方法(但绝不是有效的):

    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]
    

    如果您真的想要一个最小的示例,请不要使用Int,而是使用Tree ()Tree Bool

    【讨论】:

      猜你喜欢
      • 2014-09-18
      • 2013-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-14
      相关资源
      最近更新 更多