2011-02-07 9 views
21

Wiem, że TypeSynomymInstances only allows fully applied type synonyms to be used in instance heads, ale wydaje się, że byłby przydatny, gdybym mógł użyć również synonimy używane do stosowania paritally.Dlaczego TypeSynonymInstances nie zezwala na stosowanie częściowo używanych synonimów w nagłówkach instancji?

na przykład:

class Example e where 
    thingy :: a -> b -> e a b 

-- legit, but awkward 
newtype FuncWrapper e a b = FuncWrapper { ap :: a -> e a b } 
instance (Example e) => Example (FuncWrapper e) where 
    thingy _ = FuncWrapper . flip thingy 
funcWrapperUse :: (Example e) => e Int String 
funcWrapperUse = thingy 1 "two" `ap` 3 `ap` 4 `ap` 5 

-- not legal, but a little easier to use 
type FuncSynonym e a b = a -> e a b 
instance (Example e) => Example (FuncSynonym e) where 
    thingy _ = flip thingy 
funcSynonymUse :: (Example e) => e Int String 
funcSynonymUse = thingy 1 "two" 3 4 5 
+0

Czy wypróbowałeś '-XTypeSynonymInstances', aby uruchomić drugą wersję (zgodnie z sugestią GHC)? – Landei

+0

@Landel: Nie podoba mi się, że 'FuncSynonym e' nie jest w pełni zastosowany. Tak więc moje pytanie. – rampion

+1

To jest (związane z) bilet [785] (http://ghc.haskell.org/trac/ghc/ticket/785), który jest oznaczony jako 'wontfix'. –

Odpowiedz

28

częściowo stosowane synonimy typu nie są dozwolone w Haskell wcale. Częściowo stosowany synonim jest faktycznie funkcją, której wejściami są typy nie stosowane, a których wynikiem jest typ. Na przykład, o to kodowanie wartości logicznych:

type True x y = x 
type False x y = y 
type Not b x y = b y x 
type And b1 b2 x y = b1 (b2 x y) y 
type Or b1 b2 x y = b1 x (b2 x y) 

Aby zdecydować, czy dwa częściowo zastosowane synonimy typu są równe, wówczas kontroler typu miałyby podjąć decyzję czy funkcje są równe. Jest to trudny problem i na ogół jest nierozstrzygalny.

+1

Wystarczająco fair. W moim przykładzie wszystko, do czego go używam, to proste podstawienie, więc byłoby miło, gdyby była opcja, aby po prostu na to pozwolić, ale potem znowu nie pracuję na GHC :). Dzięki! – rampion

9

Inną kwestią związaną z dopuszczeniem częściowo zastosowanych synonimów jest to, że wniosłyby one wnioskowanie typu, a wybór wystąpienia byłby zasadniczo niemożliwy. Załóżmy na przykład, że w kontekście jakiegoś programu chciałem użyć thingy w typie Int -> String -> Int -> (Int, String). thingy ma typ forall a b e. a -> b -> e a b, więc możemy ujednolicić a z Int i b z String, ale jeśli e może być częściowo stosowana typu synonim, możemy mieć

e = FuncSynonym (,) 

lub

e = FuncSynonym' Int (,) where type FuncSynonym' x f a b = x -> f a b 

lub nawet

e = Const2 (Int -> (Int, String)) where Const2 a x y = a 

Problem typu wnioskowania stałoby się jeszcze gorsze niż decyzja o równości funkcji; wymagałoby to rozważenia wszystkich funkcji z określonym wyjściem na danym wejściu lub podobnych bardziej skomplikowanych problemów (wyobraź sobie, po prostu próbując ujednolicić a b z Int).

Powiązane problemy