Ambiguous types occur in Haskell whenever a type variable disappears due to function application. The one you have here, read/show
is common. Here's the problem:
Let's try to read a string, this operation has the type
read :: Read a => String -> a
such that if we give it a string we'll just get a type that looks like
read "()" :: Read a => a
In other words, the type system has not yet been able to pick a concrete type---it simply knows that whatever the answer is it must be Read
able.
The problem is that if we turn back around and show this immediately we're applying a function
show :: Show a => a -> String
which also doesn't fully specify the type a
. Combining them gives us
show (read "()") :: String
and we've lost all opportunities to decide upon what that intermediate type should have been.
Due to this ambiguity, Haskell disallows such expressions. You fix it by somehow interjecting a function which completely constrains the type. A common method is to use the function asTypeOf
asTypeOf :: a -> a -> a
asTypeOf = const
which ensures that the first and second arguments have the same type.
> show (read "()" `asTypeOf` ()) :: String
"()"
In your particular example you need to determine what the a
is in NestedList a
. An easy method to doing that is to explicitly give the type of flatten
as a concrete type.
print . (flatten :: NestedList Int -> [Int]) . read $ concat args