Created
November 22, 2011 07:41
-
-
Save leepike/1385118 to your computer and use it in GitHub Desktop.
Odd behavior with stable names and type constraints.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment