2013-04-26 2 views
0

Я хочу перегрузить любого оператора. Я хочу сделать такую ​​простую функцию, которая, например, думает о перегрузке оператора .Overload == такой, что x == y
возвращает x. Или x == y возвращает x + y. Неважно, что. Можете ли вы показать мне простой пример перегрузки оператора? К сожалению, я не могу найти какой-либо пример в Интернете.любой рабочий пример перегрузки оператора в haskell

Например, когда я называю Дерево == Дерево возвращение 5 (она всегда возвращает 5. Я его выбора, она не связана с какой-либо вещи) или когда я называю 3 == 4 возвращение: 7

Я пробовал следующие коды (я нахожу его на haskell.org), но он не может скомпилироваться.

class Eq a where 
(==) ::a -> a -> Int 

instance Eq Integer where 
x == y = 5 

instance Eq Float where 
x == y = 5 

Ни ниже код не работает:

Дерево данных а = Узел | Пустой

класс Дерево где (==) :: Дерево -> Дерево -> Int

экземпляр Tree Integer, где х == у = 1

Я беру ошибку:

Ambiguous occurrence `Eq' 
It could refer to either `Main.Eq', defined at Operations.hs:4:7 
         or `Prelude.Eq', 
         imported from `Prelude' at Operations.hs:1:1 
         (and originally defined in `GHC.Classes') 
+4

попробуйте только экземпляры частей. Определение typeclass уже сделано в Prelude. Кроме того, скрыть импорт определения прелюдии. – m09

+0

то как перегружать == для деревьев и всегда возвращать 5? – oiyio

+0

Класс 'Eq', определенный в Prelude, требует, чтобы результат' == 'был' Bool', поэтому для возврата '5' вам нужно было бы скрыть это и определить свой собственный. – hammar

ответ

2

Вы не можете скрыть экземпляры импортированного модуля. См. Например: Explicitly import instances

Похоже, что «перегрузка», которую вы пытаетесь сделать, - это разрешить (==) для других типов, таких как деревья. Это легко! Просто создать новый экземпляр:

data Tree a = Leaf a | Branch [Tree a] 

instance (Eq a) => Eq (Tree a) where 
    (Leaf a) == (Leaf b) = a == b 
    (Branch a) == (Branch b) = a == b 
    _   == _   = False 

(Вы также можете просто deriveEq экземпляр)

+0

Нужно ли писать что-нибудь для перегрузки == в модуле? Например; модуль x (f), где f a = a. И приведенный выше код существует. У нас есть такой модуль x (f, '==') где ... – oiyio

+0

@ user1308990: Нет; мы фактически не можем контролировать, когда они экспортируются - они всегда экспортируются. Это называется «открытым мировым предположением» – amindfv

+0

@amindfv, «открытое мировое предположение» на самом деле является чем-то другим - предположением, что новые экземпляры всегда могут быть добавлены. – dfeuer

2

Попробуйте спрятать == из Prelude. Вам нужен только класс типа, если вы хотите, чтобы он работал по-разному для разных типов.

import Prelude hiding ((==)) 

x == y = x 
+0

Как указать типы x и y, если x и y - тип Tree? Дерево a = узел a | Пусто – oiyio

+0

@ user1308990: Я не совсем уверен, что вы имеете в виду, но вы можете просто сделать то же, что и для любой функции. Операторы имеют немного другой синтаксис. – hammar

+0

ОК. Я понял. Я делаю это, чтобы понять, как работает перегрузка. Теперь понятно. Однако у меня тоже есть один вопрос, и я прокомментировал вопрос ниже ответа @amindfv. Не могли бы вы это очистить? Спасибо – oiyio

0

Вот +++ оператор, который действует как оператор (++) используется для добавления списков:

(+++) :: [a]->[a]->[a] 
x +++ [] = x 
[] +++ x = x 
x +++ y = (init x) +++ ((last x) : y) 
+0

Что этот ответ добавляет к предыдущим? – dfeuer