RE: weird (bug?) in linear implicit parameters

Yes, this is odd behaviour. Here's what is is happening. Consider foo :: %x::T => Int -> [Int] foo 0 = [] foo n = %x : foo (n-1) where T is some type in class Splittable, Do you get a list of all the same T's or all different T's? (assuming that split gives two distinct T's back) If you supply the type signature, taking advantage of polymorphic recursion, you get what you'd probably expect. Here's the translated term, where the implicit param is made explicit: foo x 0 = [] foo x n = let (x1,x2) = split x in x1 : foo x2 (n-1) But if you don't supply a type signature, GHC uses the Hindley Milner trick of using a single monomorphic instance of the function for the recursive calls. That is what makes Hindley Milner type inference work. So the translation becomes foo x = let foom 0 = [] foom n = x : foom (n-1) in foom Result: 'x' is not split, and you get a list of identical T's. That's why adding the type sig changes the behaviour. You may say that this is a good reason to dislike linear implicit parameters and you'd be right. That is why they are an experimental feature. Unlike many other features in GHC I am far from sure that it's a good one. I'll dump this message into the user manual. Simon | -----Original Message----- | From: Hal Daume III [mailto:hdaume@ISI.EDU] | Sent: 23 July 2002 18:56 | To: GHC Users Mailing List | Subject: weird (bug?) in linear implicit parameters | | | (guess who finally decided to learn about imp params :P) | | this looks like a bug to me, but of course i may be wrong. | | consider these definitions: | | > data BLSupply = BLSupply [Bool] | > | > instance Splittable BLSupply where | > split (BLSupply l) = (BLSupply (True:l), BLSupply (False:l)) | > | > newBL (BLSupply bl) = bl | | basically we can name things by lists of bools | | we name lists using this function: | | > number :: (%ns :: BLSupply) => [a] -> [(a,[Bool])] | > number [] = [] | > number (x:xs) = (x,n) : number xs | > where n = newBL %ns | | which works fine. in ghci: | | *ImpParam> let %ns = BLSupply [] in number "hello" | [('h',[False]),('e',[False,True]),('l',[False,True,True]),('l' | ,[False,True,True,True]),('o',[False,True,True,True,True])] | | Whee. now here's the wierd thing. suppose we remove the | type signature | from the number function. then, in ghci: | | *ImpParam> :t number | forall a. (%ns :: BLSupply) => [a] -> [(a, [Bool])] | *ImpParam> let %ns = BLSupply [] in number "hello" | [('h',[]),('e',[]),('l',[]),('l',[]),('o',[])] | | what gives? why did it suddenly break even though it gets | the type right? | | - hal | | -- | Hal Daume III | | "Computer science is no more about computers | hdaume@isi.edu | than astronomy is about telescopes." -Dijkstra | www.isi.edu/~hdaume | | _______________________________________________ | Glasgow-haskell-users mailing list | Glasgow-haskell-users@haskell.org | http://www.haskell.org/mailman/listinfo/glasgow-haskell-users |
participants (1)
-
Simon Peyton-Jones