public
Created

Odd behavior with stable names and type constraints.

  • Download Gist
Test.hs
Haskell
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
-- Odd behavior using stable names: polymorphism with type constraints causes
-- non-termination (see the tests at the bottom).
 
module Test where
 
import System.Mem.StableName (StableName, makeStableName)
 
---------------------------------------------------------------------------------
 
type Map a = [StableName (Expr a)]
 
analyze :: Expr a -> IO (Map a)
analyze = analyzeExpr []
 
analyzeExpr :: (Map a) -> Expr a -> IO (Map a)
analyzeExpr env e@(Op e0) = do
sn <- makeStableName e
if elem sn env
then return env
else analyzeExpr (sn : env) e0
 
---------------------------------------------------------------------------------
-- Language, with one constructor
 
class Typed a where
 
instance Typed Int
 
data Expr a = Op (Expr a)
 
expr0 :: Expr a
expr0 = Op expr0
 
expr1 :: Typed a => Expr a
expr1 = Op expr1
 
expr2 :: Typed a => Expr a
expr2 = x
where x = Op x
 
---------------------------------------------------------------------------------
-- Tests
 
-- Returns 1
test0 :: IO ()
test0 = test (expr0 :: Expr Int)
 
-- Doesn't terminate!
test1 :: IO ()
test1 = test (expr1 :: Expr Int)
 
-- Returns 1
test2 :: IO ()
test2 = test (expr2 :: Expr Int)
 
test :: Expr a -> IO ()
test e = analyze e >>= putStrLn . show . length

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.