Ce sa fac cand doua instante de clase se suprapun (overlapping) ?

From HaskellWiki
Revision as of 09:27, 7 February 2008 by Ha$kell (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

. 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'.