2012-02-14 17 views
5

Sì, so che UndecidableInstances può essere cattivo. Ho davvero cercato di progettare il mio modulo in modo che esso non ne ha bisogno però ho qualcosa di simile:Come utilizzare UndecidableInstances localmente?

instance Foo x (C x y) => Bar (C x y) where 

    ... 

e la modifica renderebbe l'API sostanzialmente più brutto. Non ho mai derivato Foo di Bar quindi non c'è modo di creare un loop.

D'altra parte abilitare UndecidableInstances rende facile ignorare gli errori stupidi. Per esempio potrei scrivere per sbaglio qualcosa del tipo:

instance Foo x (C x z) => Bar (C x y) where 

    ... 

dove z compare mai sul lato destro.

Domanda: È possibile utilizzare localmente UndecidableInstances in un modulo, ovvero contrassegnare in modo esplicito i luoghi in cui vengono eliminate le normali regole di terminazione?

Ovviamente non sarà di aiuto con la terminazione, ma renderà la decisione di utilizzare questa estensione più informata.

Domanda 2: C'è qualcosa di più debole di UndecidableInstances che ancora non garantirebbe di terminazione, ma sarebbe vietare alcuni altri casi border-line, come il secondo frammento di codice?

risposta

4

Finora, le direttive di linguaggio sono per modulo, quindi la risposta alla prima domanda è no. Per quanto riguarda la seconda domanda, non ne sono del tutto sicuro, ma non conosco altre estensioni di UndecidableInstances che consentirebbero l'istanza.

Tuttavia, UndecidableInstances non è così male, ma consente semplicemente al correttore di tipi di tentare di risolvere istanze in cui non può provarlo. Tuttavia, lo stack di contesto impedisce che il loop si interrompa per sempre.