Hello,

while looking at Greg Buchholz's Joy-combinators (haskell-cafe, Friday), I 
discovered that the type inference of version 6.4.2005.022 didn't work 
correctly. The code and comments indicating the incorrectly inferred types 
are attached (Joy2.hs).
However, the implementation doesn't adhere strictly to the wrongly inferred 
types, e.g.

*Joy2> linrec (id, (id, (id, ((pop ! lit True), (3,(2,1))))))
(3,(2,1))
*Joy2> :t pop ! lit True
pop ! lit True :: (a, b) -> (Bool, b)
*Joy2> :t linrec
linrec :: (t -> t, (b -> b, (b -> t, (b -> (Bool, b), b)))) -> t,

so it might well be that only the display of the inferred type is incorrect.

As for the behaviour of :i, 
in version 6.2.2, default methods for classes were indicated, which I find a 
good idea, in 6.4.20050222 this is not so.
Further, Hugs gives more instances, e.g. for 
:i Show,
which may (or may not) be due to different exports from the Prelude,
more serious is that version 6.4.20050222 doesn't give the contexts, which is 
bad if one defines an instance like

instance (Ord a, Num a) => MyClass a where . . .,

when 
:i MyClass gives

instance MyClass a.

Maybe, this has already been taken care of, I will today install version 
6.4.20050304 and see.

Regards,
Daniel Fischer
module Joy2 where
--Joy combinators in Haskell

--main :: IO ()
main = do   print $ ((lit 6) ! fact) bot            -- factorial of 6
            print $ ((lit 2) ! square ! fact2) bot  -- factorial of 4

--bot :: String
bot = "EOS" -- end of stack

{---------------------------------------------------------------------
The inferred type of square and cube is

(Integer, a) -> (Integer, a)

in versions 6.2.2, 6.4.20050222 and Hugs.
Why not the more general

Num a => (a,b) -> (a,b) ?
---------------------------------------------------------------------}
--square :: Num a => (a,b) -> (a,b)
square = dup ! mult

--cube :: Num a => (a,b) -> (a,b)
cube = dup ! dup ! mult ! mult

--In Joy: factorial == [0 =] [pop 1] [dup 1 - factorial *] ifte
fact :: (Integer, a) -> (Integer, a)
fact =  (quote ((lit 0) ! eq)) !
        (quote (pop ! (lit 1))) !
        (quote (dup ! (lit 1) ! sub ! fact ! mult)) !
        ifte

--In Joy: [1 1] dip [dup [*] dip succ] times pop
fact2 = (quote ((lit 1) ! (lit 1)))
        ! dip ! (quote (dup ! (quote mult) ! dip ! suc))
        ! times ! pop

-- fact3,4 & 5 don't type check, fails with...
-- Occurs check: cannot construct the infinite type:

{-In Joy: [null] [succ] [dup pred] [i *] genrec
fact3 :: (Integer, a) -> (Integer, a)
fact3 = (quote nul) ! (quote suc) ! (quote (dup ! pre)) ! (quote (i ! mult))
        ! genrec

fact4 :: (Integer, a) -> (Integer, a)
fact4 = genrec.quote(mult.i).quote(pre.dup).quote(suc).quote(nul)

--In Joy:  [null]  [succ]  [dup pred]  [*]  linrec
fact5 :: (Integer, a) -> (Integer, a)
fact5 = quote(nul) ! quote(suc) ! quote(dup ! pre) ! quote(mult) ! linrec
-}

--nul :: Num a => (a,b) -> (Bool,b)
nul = (lit 0) ! eq

--suc :: Num a => (a,b) -> (a,b)
suc = (lit 1) ! add

--pre :: Num a => (a,b) -> (a,b)
pre = (lit 1) ! sub

{---------------------------------------------------------------------
Here, version 6.4.20050222 really errs, it's inferred type is

linrec :: (t -> t, (b -> b, (b -> t, (b -> (Bool, b), b)))) -> t,

version 6.2.2 and Hugs infer the correct type.
---------------------------------------------------------------------}
--linrec :: (a -> a,(b -> b,(b -> a,(b -> (Bool,c),b)))) -> a
linrec (rec2, (rec1, (t, (p, stack))))
      | fst (p stack) == True = (t stack)
      | otherwise = rec2 (linrec (rec2, (rec1, (t, (p, (rec1 stack))))))


--genrec :: ((a -> b,c) -> b,(a -> c,(a -> b,(a -> (Bool,d),a)))) -> b
genrec (rec2, (rec1, (t, (b, stack))))
      | fst (b stack) == True = (t stack)
      | otherwise = (rec2.quote(genrec.quote(rec2).quote(rec1).
                          quote(t).quote(b))) (rec1 stack)


--times :: (Ord a, Num a) => (b -> b, (a, b)) -> b
times (p, (n, stack)) | n>0 = times (p, (n-1, (p stack)))
                      | otherwise = stack

-- (!) :: (a -> b) -> (b -> c) -> a -> c
(!) f g = g.f

--i :: (b -> c, b) -> c
i    (a, b)      = (a b)
--add :: Num a => (a,(a,b)) -> (a,b)
add  (a, (b, c)) = (b+a, c)

--sub :: Num a => (a,(a,b)) -> (a,b)
sub  (a, (b, c)) = (b-a, c)

--mult :: Num a => (a,(a,b)) -> (a,b)
mult (a, (b, c)) = (b*a, c)

--swap :: (a,(b,c)) -> (b,(a,c))
swap (a, (b, c)) = (b, (a, c))

--pop :: (a,b) -> b
pop  (a, b)      =  b

--dup :: (a,b) -> (a,(a,b))
dup  (a, b)      = (a, (a, b))

--dip :: (c -> d, (b,c)) -> (b,d)
dip  (a, (b, c)) = (b, (a  c))

--eq :: Eq a => (a,(a,b)) -> (Bool,b)
eq   (a, (b, c)) | a == b    = (True, c)
                 | otherwise = (False,c)

{---------------------------------------------------------------------
Here's more or less the same error as at 'linrec', version 6.4.2005022
infers the type

ifte :: (b -> t, (b -> t, (b -> (Bool, b), b))) -> t.
---------------------------------------------------------------------}
--ifte :: (a -> t,(a -> t,(a -> (Bool,c),a))) -> t
ifte (f, (t, (b, stack))) | fst (b stack) == True = (t stack)
                          | otherwise             = (f stack)

--lit :: a -> b -> (a,b)
lit val stack      = (val, stack) -- push literals on the stack

--quote :: a -> b -> (a,b)
quote = lit
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to