在Haskell中,如何自动派生这样一个自定义类?
代码如下所示:在Haskell中,如何自动派生这样一个自定义类?,haskell,functional-programming,Haskell,Functional Programming,代码如下所示: class MyAnd a where myAnd :: (Show a) => a -> a -> String x `myAnd` y = (show x) ++ " and " ++ (show y) data TrafficLight = Red | Yellow | Green deriving(Show, MyAnd) 这里的MyAnd是一个类型类,它有一个函数MyAnd,我认为它是泛型的,唯一的限制是a必须有一个Show类的实例 在Tr
class MyAnd a where
myAnd :: (Show a) => a -> a -> String
x `myAnd` y = (show x) ++ " and " ++ (show y)
data TrafficLight = Red | Yellow | Green deriving(Show, MyAnd)
这里的MyAnd
是一个类型类,它有一个函数MyAnd
,我认为它是泛型的,唯一的限制是a
必须有一个Show
类的实例
在TrafficLight
type中,它已经派生自Show
type类。然而,当我编译代码时,编译器会抱怨
Can't make a derived instance of ‘MyAnd TrafficLight’:
‘MyAnd’ is not a derivable class
In the data declaration for ‘TrafficLight’
Failed, modules loaded: none.
有人对此有想法吗?您不能将派生用于用户定义的类。通常,
派生
会自动为给定类的方法生成代码,这是因为编译器知道这些方法应该做什么,因此可以根据类型的结构生成合适的实现。对于用户定义的类,这显然是不可能的,因为编译器无法知道这些方法应该如何运行
在您的例子中,您似乎只想使用类所拥有的一个方法的默认实现,因此不需要由编译器生成任何实现。当然,这意味着根本不需要派生
,您可以只使用实例声明而不使用主体
PS:如果您总是希望使用该方法的默认实现,那么最好不要使用类,而只是将
myAnd
定义为函数。对于这个特定问题,您可以简单地避免定义自定义类:
data TrafficLight = Red | Yellow | Green deriving Show
myAnd :: (Show a) => a -> a -> String
x `myAnd` y = (show x) ++ " and " ++ (show y)
现在,
myAnd
适用于TrafficLight
s(以及所有其他Show
able类型)。在尝试了解如何使用GHC的DeriveAnyClass
扩展时发现了这个问题,该扩展在三周前才被提出
使用它,以下功能将如您所期望的那样发挥作用:
{-# LANGUAGE DeriveAnyClass #-}
class Show a => MyAnd a where
myAnd :: a -> a -> String
x `myAnd` y = (show x) ++ " and " ++ (show y)
data TrafficLight = Red | Yellow | Green deriving (Show, MyAnd)
但是应该谨慎使用,因为它实际上会派生任何类,在必要时创建空实例。True,编译器不知道这些方法应该做什么。但也许在语言中添加一个值得一提的内容是一种表达方式。相关的: