最小化重复模式的函数重载

tes*_*n3r 1 haskell

为了学习haskell,我一直在构建一个很像Python Pandas 的框架。

在这种情况下,我定义了一个名为 Series 的数据

    data Series
  = SInt [Int] ByteString
  | SFloat [Float] ByteString
  | SByteString [ByteString] ByteString
  deriving (Show, Eq)
Run Code Online (Sandbox Code Playgroud)

但是由于 Haskell 类型系统和我的知识,我使用这种非常重复的编码模式编写了简单的函数,如标量和

sScalarSum :: Series -> Either Int Float
sScalarSum (SInt i _) = Left $ Data.List.sum i
sScalarSum (SFloat i _) = Right $ Data.List.sum i
sScalarSum (SByteString _ _) =
  error "Cannot sum strings. use applyDType to convert series to float or int"
Run Code Online (Sandbox Code Playgroud)

是否有任何形式的重载来最小化此代码?

我不能做这样的事情吗?

sScalarSum :: Series -> Either Int Float
sScalarSum (Series i _) = Left $ Data.List.sum i
Run Code Online (Sandbox Code Playgroud)

che*_*ner 11

您不需要在构造函数级别对这些信息进行编码。将 a 定义Series任何内容的参数化列表

data Series a = Series [a] ByteString
Run Code Online (Sandbox Code Playgroud)

sScalarSum仅限于可汇总类型。

sScalarSum :: Num a => Series a -> a
sScalarSum (Series values _) = Data.List.sum values
Run Code Online (Sandbox Code Playgroud)

更一般地说,您可以定义一个Foldable实例Seriessum直接在您的值上使用。

instance Foldable Series where
    foldMap f (Series values _) = foldMap f values

sScalarSum :: Num a => Series a -> a
sScalarSum = Data.List.sum
Run Code Online (Sandbox Code Playgroud)