Ce sa fac cand doua instante de clase se suprapun (overlapping) ?
. Ce sa fac cand doua instante de clase se suprapun (overlapping) ?
Problema,asa cum a venit:
-- Acest cod produce o eroare interesanta:
class A a where
f :: a -> a
instance A a => A ( a -> a ) where
f x = \ z -> f (x (let y = y in y))
instance A ( a -> a ) => A a where
f x = f (\ y -> x)
. Observatii
A trebuit sa activez si extensia -98 a lui hugs. Iata ce am obtinut:
ERROR "eroareinteresanta2.hs":9 - Overlapping instances for class "A"
*** This instance : A a
*** Overlaps with : A (a -> a)
*** Common instance : A (a -> a)
. Comentarii
Spre deosebire de functii in ecuatiile carora putem pune doua cazuri care se suprapun (unul fiind generalizarea celuilalt) la instante de clasa nu putem face acest lucru.
La functii treaba este in regula deoarece sunt incercate in ordine variantele si prima gasita in acea ordinea decide. Exemplu:
f 0 0 = 1
f x 0 = 0
Ceea ce va duce fireste la concluzia ca f 0 0 este 1.
Ei bine, spre deosebire de functii, instantele claselor par sa nu fie tratate ca o lista ordonata ci ca o multime de declarartii care specifica lucruri distincte inclusiv prin faptul ca unul nu e generalizarea celuilalt.
Mai sus, deoarece tipul a poate fi oricare inclusiv un a -> a cele doua instante se suprapun, rezultand o ambiguitate.
. Propunere de solutie
Pentru a evita confuzia intre a-uri si a->a poti folosi liste de un element care au tipul [a] in locul elementelor de tipul a. Bineinteles functiile f trebuie rescrise corespunzator.
module Eroare2 where
class A a where
f :: a -> a
instance A [a] => A ( [a] -> [a] ) where
-- f x = \ z -> f (x (let y = y in y)) -- dar aveti de rescris f,dupa nevoi, cu liste
instance A ( [a] -> [a] ) => A [a] where
-- f x = f (\ y -> x) -- dar aveti de rescris f, dupa nevoi, cu liste
. Raspuns pe scurt
Ce sa fac cand doua instante de clase se suprapun (overlapping) ?
Incercati sa reprezentati tipurile cu care lucrati astfel ca instantele sa nu se suprapuna :) O idee in acest caz (a versus a-> a) ar fi ca [a] nu se suprapune nici cu a->a nici cu [a] -> [a]. Primele sunt liste ultimele sunt functii. Se pot folosi si alti constructori de tipuri nu neaparat cel de la liste pentru a construi solutii.
Dupa o intrebare pusa de Cristian B. (7 feb 2008)
Pagina indexata la indexul Categories:Ro
<= Inapoi la pagina principala Ro/Haskell.
<- Inapoi la inceputul paginii 'Intrebarile incepatorului Ro/Haskell'.