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