How can you unlock instances to actually hang the compiler?

By the time I first read the serious criticism on-XUndecidableInstances , I was completely used to it, seeing it only as removing the annoying restriction of Haskell98 should simplify the implementation of compilers.

In fact, I came across many applications where insoluble instances are needed, but not where they actually caused unsolvability problems. Luke's example is problematic for another reason.

class Group g where
  (%) :: g -> g -> g
  ...
instance Num g => Group g where
  ...

- well, that would be clearly overlapped by any appropriate Groupexample, so insolubility is the least of our concern: it is actually un <determinate>

!

But rightly, I have since kept “unsolvable instances, possibly hung the compiler” in the back of my head.

Where did it get from when I read this problem on CodeGolf.SE asking for code that the compiler would hang indefinitely. Well, that sounds like work for insoluble instances, right?

Turns out I can't get them to do this. The following compilations as soon as possible, at least from GHC-7.10:

{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
class C y
instance C y => C y
main = return ()

I can even use class methods and they will only call the loop at runtime:

{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}
class C y where y::y
instance C y => C y where y=z
z :: C y=>y; z=y
main = print (y :: Int)

But the loops are not unusual at runtime; you can easily copy them to Haskell98.

I also tried different, less straight loops like

{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
data A x=A
data B x=B
class C y
instance C (A x) => C (B x)
instance C (B x) => C (A x)

Again, there are no problems during compilation.

So what does it really take to hang the compiler in resolving instances of a class of unesidable type?

+4
3

, - . , . , , , .

data A x = A deriving (Show)
class C y where get :: y
instance (C (A (A a))) => C (A a) where
    get = A

main = print (get :: A ())

• Reduction stack overflow; size = 201
  When simplifying the following type:
    C (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A (A ())))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))
  Use -freduction-depth=0 to disable this check
  (any upper bound you could choose might fail unpredictably with
   minor updates to GHC, so disabling the check is recommended if
   you're sure that type checking should terminate)

, , . , , .

-, GHC.

+10

" " - :

type family Loop where
  Loop = Loop

foo :: Loop
foo = True

GHC. , GHC 7.11, :

data T where
    T :: forall (t :: T). T

.

+6

, UndecidableInstances GHC. , :

{-# LANGUAGE FlexibleInstances     #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies          #-}
{-# LANGUAGE UndecidableInstances  #-}
module Nested where

class Nested r ix where

type family Lower ix :: *

data LN

instance Nested LN (Lower ix) => Nested LN ix where

data L

instance Nested LN ix => Nested L ix where

( ghc main.hs) GHC 8.2.1

@luqui, , : https://ghc.haskell.org/trac/ghc/ticket/14402

. , ​​ GHC.

+2
source

Source: https://habr.com/ru/post/1670350/


All Articles