使用转换函数来创建类型类的实例

men*_*ics 1 haskell typeclass

比方说我有:

data MyType
myToDouble :: MyType -> Double
Run Code Online (Sandbox Code Playgroud)

假设我希望MyType是Num或Real的实例,或者是Double已经是其实例的东西.

是否有一种简单的方法可以实现这一点而无需手动写出Num/Real中的所有方法?

那么......有什么方法可以说:

instance Real MyType by way of myToDouble
Run Code Online (Sandbox Code Playgroud)

luq*_*qui 5

当然不; Real依赖于Num,并且Num具有返回a(或更准确地说,是协变的a)方法.你打算如何实施:

(+) :: MyType -> MyType -> MyType
Run Code Online (Sandbox Code Playgroud)

只是MyType和myToDouble?

现在也许你已经拥有了所有其他实例并且只是想知道Real.嗯,唯一的方法Real是它自己的toRational,所以:

instance Real MyType where
    toRational = toRational . myToDouble
Run Code Online (Sandbox Code Playgroud)

至于你更普遍的问题:遗憾的是没有.如果你有一个类的方法都是逆变量(只作为参数)在类型变量中,那么你应该能够在这样的投影上自动定义一个类型类.但是Haskell没有这样做的机制.(您可以使用Template Haskell自己编写一个).

您可以使用将"新类型"实例"转发"到其基础类型GeneralizedNewtypeDeriving.例如.

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

newtype MyType = MyType Double
    deriving (Eq,Ord,Show,Num,Real)
Run Code Online (Sandbox Code Playgroud)

但你不能使用任何旧的同构.这是一个耻辱.