一旦我成功解决了Functor类型类的练习:
data ExactlyOne a = ExactlyOne a deriving (Eq, Show)
instance Functor ExactlyOne where
(<$>) ::
(a -> b)
-> ExactlyOne a
-> ExactlyOne b
(<$>) f a = ExactlyOne $ f (runExactlyOne a)
解决另一个练习,我需要为自定义Odd类型定义Enum类型类函数。
data Odd = Odd Integer
deriving (Eq, Show)
instance Enum Odd where
-- succ :: Odd -> Odd <-- error
succ (Odd x) = Odd $ x + 2
现在,当我尝试为更简单的功能指定类型签名时,ghci给出了一个错误:
实例声明中的非法类型签名: succ ::奇数->奇数(使用InstanceSigs允许)
没有它就可以工作,但是我想知道为什么会产生此错误,以及如何为此功能正确指定类型签名?
答案 0 :(得分:6)
实例中的签名对于类型类中的类型签名是多余的。如果您稍后稍稍更改类型类的签名(例如,通过添加额外的类型约束),则可能仅由于签名不再协调而可能导致错误。
这是在section on Instance Declarations in the Haskell '10 report中指定的:
声明不得包含任何类型签名或固定性声明,因为这些声明已在类声明中提供。与默认类方法(第4.3.1节)一样,方法声明必须采用变量或函数定义的形式。
Enum
typeclass [src]已包含签名:
class Enum a where -- | the successor of a value. For numeric types, 'succ' adds 1. succ :: a -> a -- ...
但是,如果您想指定签名,则可以打开InstanceSigs
language extension [ghc-doc],例如:
{-# LANGUAGE InstanceSigs #-}
data Odd = Odd Integer deriving (Eq, Show)
instance Enum Odd where
succ :: Odd -> Odd
succ (Odd x) = Odd $ x + 2