Q: Resolving ambiguous type variable

Hal Daume III hdaume@ISI.EDU
Fri, 17 May 2002 11:58:29 -0700 (PDT)


The problem is that a is still ambiguous.  For instance, look at the
difference between:

  show ([] :: [Int])        ==>   []
  show ([] :: [Char])       ==>   ""

because character lists are shown between quotes.  so even though we know
that this type variable a is an instance of show, we still don't know how
to show it (i.e., "we don't know which dictionary to use to lookup the
show function for the datatype").

--
Hal Daume III

 "Computer science is no more about computers    | hdaume@isi.edu
  than astronomy is about telescopes." -Dijkstra | www.isi.edu/~hdaume

On Fri, 17 May 2002 tty@SAFe-mail.net wrote:

> Would it be correct to conclude from your reasoning that the following would be properly typed by the compiler ?
> 
> first_h :: (Show a) => [a] -> Result a
> first_h [] = Ex "No list"
> first_h (x:xs) = Value x
> 
> since we are explicitly stating first_h can only take a list containing elements deriving Show. My expectations would be that this would be unambiguous, unfortunately ghc-5.02.3 
> still complains with the reported error.
> 
> Regards
> 
> Tee
> 
> -------- Original Message --------
> From: hdaume@ISI.EDU
> To: tty@SAFe-mail.net
> Cc: haskell-cafe@haskell.org
> Subject: Re: Q: Resolving ambiguous type variable
> Date: Fri, 17 May 2002 10:24:29 -0700 (PDT)
> 
> > Erm, I think I said something stupid (or at least implied it).
> > 
> > main = getArgs >>= print . first_h
> > 
> > *will* work, because it knows that the result of a getArgs is a list of
> > Strings.
> > 
> > The problem you originally had was that when you say:
> > 
> > first_h []
> > 
> > The "[]" could refer to a list of any type of element.  Since not every
> > element type is an instance of Show, it doesn't know that it can apply
> > show to the list.
> > 
> > By saying, for instance, (first_h ([] :: [Char])) you're saying "okay,
> > this is an empty list, but it's a list of Characters and you know that a
> > character can be shown."  If you backtrack what the type checker is doing,
> > it says:
> > 
> > print (first_h [])
> > 
> > okay, the argument to print must be an instance of Show (print has type
> > Show a => a -> IO ()).  therefore,
> > 
> > first_h []
> > 
> > must be an instance of Show.  well, what's the type of first_h []?  Well,
> > the type of first_h is [a] -> Result a.  is "Result a" an instance of
> > show?  well, let's see...you said data Result a = ... deriving
> > (Show).  this basically means you get an instance declaration:
> > 
> > instance Show a => Show (Result a) where
> >   ...some stuf...
> > 
> > so, we want to know if Result a is an instance of show.  Well, it is
> > whenever a is an instance of show.  so, if the elements of your list are
> > an instance of show, then (first_h []) is an instance of Show, as we
> > require.
> > 
> > however, since you just say "[]" it knows this is of type [a], but it
> > *doesn't* know what a is.  therefore, a could either be or not be an
> > instance of show.  however, if you explicitly specify what a is and that
> > explicit type is an instance of show (like Char in my example), then
> > everything is fine.
> > 
> > --
> > Hal Daume III
> > 
> >  "Computer science is no more about computers    | hdaume@isi.edu
> >   than astronomy is about telescopes." -Dijkstra | www.isi.edu/~hdaume
> > 
> > On Fri, 17 May 2002, Hal Daume III wrote:
> > 
> > > In short, you cannot.
> > > 
> > > What if your main were:
> > > 
> > > main = getArgs >>= print . first_h
> > > 
> > > The compiler doesn't know the difference and so it needs a type.
> > > 
> > > Simple fix:
> > > 
> > > > main = print (first_h ([] :: [Char]))
> > > 
> > > 
> > > --
> > > Hal Daume III
> > > 
> > >  "Computer science is no more about computers    | hdaume@isi.edu
> > >   than astronomy is about telescopes." -Dijkstra | www.isi.edu/~hdaume
> > > 
> > > On Fri, 17 May 2002 tty@SAFe-mail.net wrote:
> > > 
> > > > Hello,  
> > > >    I am writing a function which returns an exception/error string should an unexpected parameter is passed in. Borrowing from the Maybe module I have the following:
> > > > ------------------------------------------------------------
> > > > data Result a = Ex String | Value a deriving Show
> > > > 
> > > > -- Testing the Result a type
> > > > first_h :: [a] -> Result a
> > > > first_h [] = Ex "No list"
> > > > first_h (x:xs) = Value x
> > > > 
> > > > -- Trying out the first_h
> > > > main :: IO()
> > > > main = print (first_h [])
> > > > ------------------------------------------------------------
> > > > 
> > > > Which the compiler complains:
> > > > 
> > > > Ambiguous type variable(s) `a' in the constraint `Show a'
> > > >     arising from use of `print' at atype.hs:8
> > > >     In the definition of `main': print (first_h [])
> > > > 
> > > > This is understandable since it is unable to unify the empty list with a concrete list of type 'a' i.e. there are an infinite types which would match. My question is how can I indicate to the compiler that it does not matter which type the empty list is since the return result is of a concreate type.
> > > > 
> > > > Thanks
> > > > 
> > > > Tee
> > > > _______________________________________________
> > > > Haskell-Cafe mailing list
> > > > Haskell-Cafe@haskell.org
> > > > http://www.haskell.org/mailman/listinfo/haskell-cafe
> > > > 
> > > 
> > > _______________________________________________
> > > Haskell-Cafe mailing list
> > > Haskell-Cafe@haskell.org
> > > http://www.haskell.org/mailman/listinfo/haskell-cafe
> > >
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe
>