You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何消除重复函数并为不同类型实现Binary实例?

解决重复函数的方案

完全可以移除这些重复的函数!核心思路是把通用逻辑提取成多态辅助函数,让两个Binary实例共享同一段代码,不用为不同类型写重复实现。

具体实现思路

1. 提取通用函数消除重复

假设你的yes和yes'、..>和~.>逻辑完全一致,只是类型签名适配不同的数据类型,那可以先把核心逻辑抽成多态的通用版本:

-- 通用版yes逻辑
yesGeneric :: Binary b => ... -> b
yesGeneric = -- 这里写原来yes/yes'的核心实现

-- 通用版组合操作符逻辑
genericCombine :: Binary a => ... -> ... -> ...
genericCombine x y = -- 原来..>/~.>的核心实现

然后在两个Binary实例里直接复用这些通用函数:

instance Binary TypeA where
  put = ... yesGeneric ... genericCombine ...
  get = ... yesGeneric ... genericCombine ...

instance Binary TypeB where
  put = ... yesGeneric ... genericCombine ...
  get = ... yesGeneric ... genericCombine ...

2. 用自定义类型类进一步抽象

如果你的两个类型序列化逻辑高度相似,还可以定义一个专属类型类,把业务相关的序列化逻辑抽离出来,再基于它实现Binary实例:

class MySerializable a where
  serialize :: a -> Put
  deserialize :: Get a

-- 为两个类型实现自定义序列化逻辑
instance MySerializable TypeA where
  serialize = -- 通用序列化逻辑
  deserialize = -- 通用反序列化逻辑

instance MySerializable TypeB where
  serialize = -- 通用序列化逻辑(和TypeA一致的话可以写默认实现)
  deserialize = -- 通用反序列化逻辑

-- Binary实例只做一层转发,彻底消除重复
instance Binary TypeA where
  put = serialize
  get = deserialize

instance Binary TypeB where
  put = serialize
  get = deserialize

3. 用DerivingVia简化实例定义(GHC 8.6+)

如果用的是较新的GHC版本,还可以借助DerivingVia扩展,通过通用newtype包装来共享实例:

{-# LANGUAGE DerivingVia #-}

newtype GenericBinary a = GenericBinary a

instance MySerializable a => Binary (GenericBinary a) where
  put (GenericBinary x) = serialize x
  get = GenericBinary <$> deserialize

-- 直接通过DerivingVia复用通用实现
data TypeA = ... deriving (Binary) via (GenericBinary TypeA)
data TypeB = ... deriving (Binary) via (GenericBinary TypeB)

关键总结

  • 核心是抽离通用逻辑,避免为不同类型写重复的序列化/反序列化代码
  • 多态函数、自定义类型类、DerivingVia都是消除重复的有效手段,可根据你的代码复杂度选择合适的方式

内容的提问来源于stack exchange,提问作者BlackCap

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:24:54