Использование функции преобразования для создания экземпляра класса типа - PullRequest
1 голос
/ 02 апреля 2011

Допустим, у меня есть:

data MyType
myToDouble :: MyType -> Double

Допустим, я хочу, чтобы MyType был экземпляром Num или Real или чем-то, что Double уже является экземпляром.способ сделать это без необходимости выписывать вручную все методы в Num / Real для этого?

Итак ... есть ли способ просто сказать:

instance Real MyType by way of myToDouble

1 Ответ

5 голосов
/ 02 апреля 2011

Определенно нет;Real зависит от Num, а Num имеет методы, которые возвращают a (или, точнее, ковариантны в a).Как вы собираетесь реализовать:

(+) :: MyType -> MyType -> MyType

, данные только MyType и myToDouble?

Теперь, может быть, у вас уже есть все другие экземпляры и вы просто интересуетесь Real.Ну, единственный метод Real имеет свой собственный toRational, поэтому:

instance Real MyType where
    toRational = toRational . myToDouble

Что касается вашего более общего вопроса: к сожалению, нет.Если у вас есть класс, все методы которого являются противоречивыми (принимают только в качестве аргументов) в переменной типа, то вы должны иметь возможность автоматически определять класс типов в проекции, подобной этой.Но у Хаскелла нет механизма для этого.(Вы можете написать его самостоятельно, используя Template Haskell).

Вы можете"переслать" экземпляры нового типа в его базовый тип, используя GeneralizedNewtypeDeriving.Например,

{-# LANGUAGE GeneralizedNewtypeDeriving #-}

newtype MyType = MyType Double
    deriving (Eq,Ord,Show,Num,Real)

Но вы не можете использовать какой-либо старый изоморфизм.Обидно.

...