13

我有这个

data Something = Something Integer deriving (MyClass, Show)

class MyClass a where   
    hello :: MyClass a => a -> a

instance MyClass Integer where
    hello i = i + 1

main = print . hello $ Something 3

但 MyClass 不可派生。为什么?

4

2 回答 2

13

GHC 不能神奇地为任意数据类型派生实例。但是,它可以利用newtype声明为相同的底层类型创建一个新名称的事实来为使用 GeneralizedNewtypeDeriving扩展的那些派生实例。所以,你可以这样做:

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

newtype Something = Something Integer deriving (MyClass, Show)

class MyClass a where
    hello :: MyClass a => a -> a

instance MyClass Integer where
    hello i = i + 1

main = print . hello $ Something 3

GHC 无法派生新实例的原因是它不知道该实例应该是什么。即使您的数据类型只有一个字段,它也不一定与该字段相同。为newtypes 派生实例的能力很方便,因为它们通常用于为某些类型类提供不同的行为,或者作为使用类型系统来分离代码中具有相同类型但用途不同的事物的一种方式。

于 2013-02-07T16:08:40.333 回答
13

You may want to have a look at the GHC documentation on Generic Programming.
You need to create a class that can work on a generic representation of arbitrary types. I don't think the specific example you gave is reasonable for a derivable class.

于 2013-02-07T16:26:59.333 回答