[Haskell-cafe] List as input

Luke Palmer lrpalmer at gmail.com
Fri Oct 17 09:31:35 EDT 2008


On Fri, Oct 17, 2008 at 7:21 AM, leledumbo <leledumbo_cool at yahoo.co.id> wrote:
>
> So, what's the solution? This one:
>
> (l::[Ord]) <- readLn
>
> doesn't work (because Ord isn't a type constructor). It doesn't even comply
> to Haskell 98 standard. I want to be able to read any list of ordered
> elements.

What you're after is not possible that easily.   What you want to do
is to read a bunch of elements, and based on what you read in,
determine their type.  This is contrary to static typing.

A number of ways are possible, but they all involve some sort of
enumeration of all the possible types to read in.

Way #1:  make a data type which represents any of the types of things
you can accept, and define Ordering on it.

  data Thing
    = ThingInt Int
    | ThingString String
    | ThingList [Thing]
    | ...
    deriving Ord

And then define a parser to get from a string to a Thing (pretty easy
using ReadP or Parsec or something).

Note that this would accept a heterogeneous list like 1, "foo", 2,
[3,"bar",4], and it would sort it as 1, 2, "foo", [3,"bar",4], because
of the way Ord deriving works (all Ints are less than all Strings are
less than all Lists ...).  You can customize this by not using
"deriving", and instead manually declaring the instance.

Way #2:  use the parser from way #1 to parse the first one and
determine what kind of thing you're reading, and then read a bunch of
those.

sortThings :: (Read a) => IO [a]

main = do
    first <- getLine
    case first of
      ThingInt _ -> print =<< (sortThings :: IO [Int])
      ThingString _ -> print =<< (sortThings :: IO [String])
      ...

There are some other more clever ways.  But you will not be able to
get Haskell to make the choice for you.  In particular, there are some
ambiguous choices, for example is read "42" an Int, an Integer, a
Double ?   So you need to write an algorithm which resolves the
ambiguities.

Luke


More information about the Haskell-Cafe mailing list