
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