Q: Resolving ambiguous type variable

tty@SAFe-mail.net tty@SAFe-mail.net
Fri, 17 May 2002 13:51:19 -0500


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
> >