2013-01-23 6 views
29

Załóżmy, że projektant biblioteki Haskell decyduje się na użycie UndecidableInstances z jakiegoś powodu. Biblioteka kompiluje się dobrze. Załóżmy teraz, że jakiś program używa biblioteki (np. Definiuje niektóre instancje jej klas typów), ale nie używa rozszerzenia. Czy może się zdarzyć, że kompilacja się nie powiedzie (nie zakończy się)?Czy używanie debiuty UndecidableInstances lokalnie może mieć globalne konsekwencje dla zakończenia kompilacji?

Jeśli taki scenariusz może się zdarzyć, chętnie zobaczę przykład. Na przykład, jako że mtl używa partycji UndecidableInstances, czy jest możliwe napisanie programu, który zależy od mtl (lub jakiejkolwiek innej standardowej biblioteki, która używa rozszerzenia), nie korzysta z samej UndecidableInstances, ale nie kompiluje się z powodu nierozstrzygalności?

Odpowiedz

22

Świetne pytanie!

Ogólnie jest to z całą pewnością możliwe. Rozważ ten moduł:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, UndecidableInstances #-} 

module M where 

class C a b | a -> b where 
    f :: a -> b 

instance C a b => C [a] [b] 
    where f = map f 

Kompiluje się sam w sobie. Jeśli jednak zaimportować ten moduł i określić

g x = x + f [x] 

dostaniesz

Context reduction stack overflow; size = 201 
Use -fcontext-stack=N to increase stack size to N 
    C [b] b 
In the second argument of `(+)', namely `f [x]' 
In the expression: x + f [x] 
In an equation for `g': g x = x + f [x] 

Odnośnie przypadkach MTL, nie widzę, jak coś takiego jest możliwe, ale także nie ma dowodu, że tak nie jest.

+5

Grałem z twoim rozwiązaniem i udało mi się go zredukować do 'klasy C a gdzie f :: a -> a' i' instancji C [[a]] => C [a] gdzie f = id' , który nie wymaga żadnego innego rozszerzenia, ale "UndecidableInstances". –

+4

Po zbadaniu go 'mtl', uważam, że nie można spowodować, że kompilator zapętli się, używając go. Jedynym powodem, dla którego potrzebuje rozszerzenia, jest to, że niektóre z jego wystąpień zawodzą w Warstwie pokrycia (http://www.haskell.org/ghc/docs/7.0.1/html/users_guide/type-class-extensions.html# reguły instancji). Ale idea warunku jest spełniona - wszystkie zmienne typu rhs można wywnioskować z deklaracji instancji 'mtl '. –

+0

Huh, jestem zaskoczony 'C [[a]]' nie wymaga 'FlexibleContexts'. –

Powiązane problemy