当前位置: 首页 > 知识库问答 >
问题:

在typeclass实例中提供函数类型签名时会出现错误

令狐晟
2023-03-14
data ExactlyOne a = ExactlyOne a deriving (Eq, Show)

instance Functor ExactlyOne where
  (<$>) ::
    (a -> b)
    -> ExactlyOne a
    -> ExactlyOne b
  (<$>) f a = ExactlyOne $ f (runExactlyOne a)
data Odd = Odd Integer
  deriving (Eq, Show)

instance Enum Odd where
  -- succ :: Odd -> Odd <-- error
  succ (Odd x) = Odd $ x + 2

实例声明中的非法类型签名:succ::odd->Odd(使用InstanceSigs允许这样做)

没有它也能工作,但我想知道为什么会产生这个错误,如何为这个函数正确指定类型签名?

共有1个答案

况嘉运
2023-03-14

实例中的签名对于类型类中的类型签名来说是多余的。如果稍后稍稍更改typeclass的签名,例如添加额外的类型约束,则可能只因为签名不再协调而导致错误。

这在Haskell'10报告中关于实例声明的一节中指定:

声明不能包含任何类型签名或固定性声明,因为它们已经在类声明中给出了。在缺省类方法的情况下(第4.3.1节),方法声明必须采用变量或函数定义的形式。

class  Enum a   where
    -- | the successor of a value.  For numeric types, 'succ' adds 1.
    succ                :: a -> a
    -- ...
{-# LANGUAGE InstanceSigs #-}

data Odd = Odd Integer deriving (Eq, Show)

instance Enum Odd where
  succ :: Odd -> Odd
  succ (Odd x) = Odd $ x + 2
 类似资料:
  • 我试图做到以下几点:一个模板化的类应该提供一些函数,这些函数取决于它模板化的类型是否包含一个具有给定名称的成员变量。作为示例,下面的伪代码应该只在模板化的结构/类具有名为“id”的成员时才提供“printId()”: 通过研究SFINAE,traits,std::enable_if和StackOverflow,我认为这是可以做到的...但是我不知为什么没有将enable_if与以下问题中的片段结合

  • org.springframework.web.util.NestedServletException:请求处理失败;嵌套异常为java.lang.IllegalArgumentException:为类com.DatabaseProject.Questor.Model.Question提供了错误类型的id。应为:class java.lang.Integer,got class java.lang

  • 在过去一周左右的时间里,我一直在为Scala开发一个类型化、索引化的数组特性。我希望将该特征作为类型类提供,并允许库用户以他们喜欢的方式实现它。下面是一个示例,使用列表的列表来实现2D数组类型类: 这一切看起来都很好。我遇到的困难是,我希望将索引类型约束为一个已批准类型的列表(用户可以更改)。由于程序不是所有已批准类型的原始所有者,所以我想用一个typeclass来表示这些已批准类型,并让已批准类

  • 我有一个带有8个JCombobox和文本字段的Jframe...当我按下提交按钮时得到了数据类型不匹配错误 如何解决这个错误?

  • 我正在尝试制作一些适用于数字的通用函数,但我正在努力处理函数签名。 也许我是从错误的角度来讨论这个问题,但到目前为止,我是在这里独立完成的。我并不是一心要这样做;因此,如果我从错误的角度来解决这个问题(创建一个通常有用的数学函数库),那么一定要教育我。 假设我想要一个函数,将两个数字相加: 这不会编译。这里是一个游乐场:https://play.integer32.com/?version=sta

  • 我是Haskell的初学者,正在尝试学习类型类和类型。我有以下示例(它代表了我正在研究的代数中的一个实际问题),其中我定义了一个仅包装Num实例的类型,以及一个定义二进制操作的typeclass。 当将定义为此实例时,我意识到我希望能够使用类型“改变”函数。需要说明的是:我想提供一个函数,并返回一个新的类型,它是的一个实例。假设我想这样做5次、10次,唯一的区别是不同的函数。上面的代码我当然可以复