Celem tej części kodu jest uczynienie funkcji size
bardziej wydajną niż po prostu zliczanie wszystkich elementów w elems
. Postanowiłem zsumować dwa typy, które tworzą listę, ale nie mogę stworzyć sygnatury funkcji rozmiaru.W jaki sposób dopasowujesz się do typu "A a b"?
instance (Finite a, Finite b) => Finite (Either a b) where
elems = combineLists [Left x | x <- elems] [Right x | x <-elems]
size ??? = (size a) + (size b)
Z Prelude wiemy, że Either a b = Left a | Right b
.
Pierwszą rzeczą, którą próbowałem, było dopasowanie Either
, ale oczywiście jest to typ, więc to nie działa. Następnie wypróbowałem ((Left a) | (Right b))
, ale nie mogę też tego zrobić. Nic innego nie wydaje się pasować do typu Either a b
.
udało mi się dostać size (Left a)
skompilować, ale ponieważ brakuje składnika b
, otrzymuję błąd:
Ambiguous type variable `b' in the constraint:
`Finite b' arising from a use of `size' at <interactive>:1:0-12
co oczywiście ma sens w kontekście, ale naprawdę nie mam pojęcia jak mecz Either a b
.
Ktoś ma jakieś myśli?
Wygląda na nieco zakłopotanego różnicą między typem a konstruktorem. "Albo a b" jest typem z dwoma konstruktorami "lewy" i "prawy". Typy przechodzą w sygnaturach typów, podczas gdy konstruktorzy przechodzą kod. Jest to powszechne zamieszanie, ponieważ wiele typów używa tej samej nazwy dla typu i konstruktora, jak w "data Foo = Foo Int String"; pierwszy "Foo" to typ, a drugi to konstruktor. –