[Yhc] single element tuple
Tom Shackell
shackell at cs.york.ac.uk
Fri Mar 14 11:04:08 EDT 2008
> Hi,
>
> Printing the core one of my programs I see:
>
> data Prelude;1() a =
> Preluse;1() a
>
> What is this? A single element tuple? I didn't think Haskell had
> these. My program has a monad similar to IO. It appears these
> Prelude;1() things are created in the lambda lifted version of f1.
> Perhaps is it the parenthesis around (System m)?
Indeed Yhc has the 1 tuple. You can't write it in any programs but the
compiler does generate things that use it. The reason is that classes
are implemented as tuples of functions. For example
instance Eq MyData where
x == y = False
x /= y = True
f :: [MyData] -> MyData -> Bool
f ds d = elem d ds
elem :: Eq a => a -> [a] -> Bool
elem x [] = False
elem x (y:ys) | x == y = True
| otherwise = elem x ys
this is compiled into something along the lines of
dict_Eq_MyData = ( eq_Eq_MyData, neq_Eq_MyData )
eq_Eq_MyData x y = False
neq_Eq_MyData x y = True
(==) (eq,neq) = eq
f ds d = elem dict_Eq_MyData d ds
elem dict x zs =
case zs of
[] -> False
(:) y ys -> if ((==) dict) x y then True
else elem dict x ys
The question is, what do you get when your class only has one method?
The answer is a one-tuple.
dict_OneMethodClass_MyData = 1( ... )
I can't see specifically why your example would create one-tuples as
arguments to f1. However you can bet that it is related to class
dictionaries, since (as far as I know) that is the only way one-tuples
can be created.
> data Return a = Return a World
> data System a = System (World -> Return a)
> data World = World
> instance Monad System where
> (System m) >>= k = System f1
> where
> f1 w = f2 w'
> where
> Return r w' = m w
> System f2 = k r
>
> return a = System (\ w -> Return a w)
This should compiled into something like:
dict_Monad_System =
( bind_Monad_System, seq_default, return_Monad_System, fail_default )
bind_Monad_System n k =
case n of
System m -> System (f1 m k)
return_Monad_System a = System (lambda1 a)
f1 m k w =
let Return r w' = m w
System f2 = k r
in f2 w
lambda1 a w = Return a w
At least if my hand lambda lifting is correct :) As I say, I can't see
how you'd end up with a 1-tuple being passed to f1. Though if you paste
the Yhc-Core that you get then I'd be happy to look at it :)
> It's a bit difficult to correlate arguments of lifted lambdas to the
> original source. Is there a convention YHC uses for adding the extra
> arguments to lifted lambdas?
Additional arguments tend to get added to the front of the function, if
I remember correctly. Simply because it makes life easier with currying.
Hope that helps :)
Tom
P.S. you can make your 'System' type a 'newtype' rather than a 'data',
which will make it a bit quicker :) Also your 'Return' type probably
doesn't actually need to return the 'World' since there is no way it
could sensibly be modified. Thus the following would probably be
equivalent/better.
data Return a = Return a
newtype System = System (World -> Return a)
but note that the 'Return' type couldn't be a newtype because that would
change the semantics from Lazy to Strict.
More information about the Yhc
mailing list