带约束的Haskell实例

时间:2015-11-08 23:25:45

标签: haskell typeclass

我试图为签名数字类型创建一个类型类。这是我的代码:

{-# 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,但这似乎解决了我的另一个问题。我不这么认为 我的代码中存在语法错误。

1 个答案:

答案 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