额外模块中不常见的类型类的实例声明

时间:2015-12-13 20:16:37

标签: haskell typeclass

将非常规类型类的实例声明放在额外的模块中是不错的样式?

作为一个例子,我有这种简单的树类型:

module Data.Tree where

data Tree a = Leaf a
            | Node (Tree a) (Tree a)

假设我想使用QuickCheck的Arbitrary类型类来生成Tree类型的随机值(并且不仅可以在测试中使用它们)。

什么是最好的?将它们放在定义Tree的同一模块中

module Data.Tree where

import QuickCheck.Arbitrary

data Tree a = ...

instance Arbitrary a => Arbitrary (Tree a) where
    ...

或将实例声明外包给另一个模块以避免依赖于QuickCheck.Arbitrary中的Data.Tree

module Data.Tree.Arbitrary where

import Data.Tree
import QuickCheck.Arbitrary

instance Arbitrary a => Arbitrary (Tree a) where
    ...

或其他完全不同的东西?

1 个答案:

答案 0 :(得分:3)

避免孤儿实例通常是一个好主意:那些总是对惊喜有好处,而且很难找到。

所以,是的,将实例放在定义Tree的模块中。这会使模块爆炸一点,但它不应该是一个问题。在整个软件包的总构建时间中,如果你有一个更大的模块或两个更小的模块,这应该没那么重要。

如果可以完全避免程序包依赖性,这可能会使孤立实例变得有价值,因为安装程序包显然比从已安装的程序包导入模块要大得多。