我试图为签名数字类型创建一个类型类。这是我的代码:
{-# LANGUAGE TypeFamilies, FlexibleContexts, UndecidableInstances #-}
data Sign = Negative | Zero | Positive
deriving (Eq, Ord, Read, Show)
class Signed a where
sign :: a -> Sign
instance Signed Integer where
sign = undefined
这是编译,但我想调整此代码以适用于任何Integral a
。
instance (Integral a) => Signed a where
sign = undefined
此时无法编译。
我已经检查了Haskell type family instance with type constraints,但这似乎解决了我的另一个问题。我不这么认为 我的代码中存在语法错误。
答案 0 :(得分:2)
尝试编译代码会产生以下错误消息:
sign.hs:9:26:
Illegal instance declaration for ‘Signed a’
(All instance types must be of the form (T a1 ... an)
where a1 ... an are *distinct type variables*,
and each type variable appears at most once in the instance head.
Use FlexibleInstances if you want to disable this.)
In the instance declaration for ‘Signed a’
Failed, modules loaded: none.
正如编译器指出的那样,您需要打开FlexibleInstances
以及UndecidableInstances
。 GHC的错误消息通常非常具体,特别是当您忘记打开语言扩展时。以下编译:
{-# LANGUAGE UndecidableInstances, FlexibleInstances #-}
data Sign = Negative | Zero | Positive
deriving (Eq, Ord, Read, Show)
class Signed a where
sign :: a -> Sign
instance (Integral a) => Signed a where
sign = undefined
但是,我认为Signed
类在这个例子中可能是个错误。定义(非重载)顶级函数要简单得多,不需要UndecidableInstances
(需要通常是设计气味),并且更能表达含义你的代码:“你能得到的东西”正是真实的数字。
sign :: Real a => a -> Sign
sign x
| x == 0 = Zero
| x < 0 = Negative
| otherwise = Positive