以任何数字类型作为参数的数据构造函数
Data Constructor taking any Numeric type as an argument
我想知道是否可以创建一个数据构造函数,它可以采用任何给定的 class.
而不是采用特定类型
所以不用
data Container = ContainerI Int | ContainerF Float
类似
Container::(Num a)=>a
data Container = Container a
不符合标准 Haskell。实现这一点的正常方法是让 Container
完全通用,然后在重要的函数中要求 (Num a) => Container a
。类型检查器将阻止编译试图使用 Container
和不受支持的类型的代码。
如果你真的想对此格外小心,你可以将实际的构造函数从导出列表中移除,只提供将 (Num a)
作为导出的函数,但这通常不是必需的。
举个例子,看看 Data.Set
. The reality is that for Set a
to work as intended you will need an Eq a
instance. But that restriction is only required in functions that manipulate a Set
, not the definition of Set a
本身。
你可以用 existentially-quantified data constructor 做你想做的事,像这样:
{-# LANGUAGE ExistentialQuantification #-}
data Container = forall a. Num a => Container a
但是正如 所解释的,这可能不是您真正想要的。相反,只需执行 data Container a = Container a
然后声明函数,如 f :: Num a => Container a -> _whatever
.
我想知道是否可以创建一个数据构造函数,它可以采用任何给定的 class.
而不是采用特定类型所以不用
data Container = ContainerI Int | ContainerF Float
类似
Container::(Num a)=>a
data Container = Container a
不符合标准 Haskell。实现这一点的正常方法是让 Container
完全通用,然后在重要的函数中要求 (Num a) => Container a
。类型检查器将阻止编译试图使用 Container
和不受支持的类型的代码。
如果你真的想对此格外小心,你可以将实际的构造函数从导出列表中移除,只提供将 (Num a)
作为导出的函数,但这通常不是必需的。
举个例子,看看 Data.Set
. The reality is that for Set a
to work as intended you will need an Eq a
instance. But that restriction is only required in functions that manipulate a Set
, not the definition of Set a
本身。
你可以用 existentially-quantified data constructor 做你想做的事,像这样:
{-# LANGUAGE ExistentialQuantification #-}
data Container = forall a. Num a => Container a
但是正如 data Container a = Container a
然后声明函数,如 f :: Num a => Container a -> _whatever
.