How to parse hetero-list

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Baa
Reply | Threaded
Open this post in threaded view
|

How to parse hetero-list

Baa
Hello, All!

I have types A, B, C... They have instances of class Read, Show,
SomethingElse, ... I want to keep them as one collection. For example,
I can use such datatype for it:

  data Tags = forall a. Read a => Tags [a]

Now I want to parse "some-string" into A or B or C or ... but without
to create type's sum of A|B|C|...! All those types have `Read` instance
but Haskell will not find what instance to use, right? How to parse
string with alternatives where each alternative returns `ReadP A` or
`ReadP B`, etc? My intuition is that I should make `x <|> y <|> z <|> ...`
where x,y,z - parses string into A, B, C, ... so they are
expressions like `readPrec :: ReadPrec A`, etc. But how to pass types
into such expression? I must to make expression folding (with `<|>`)
`readPrec::someType`, where `someType` is item of types list `{A, B, C, ...}`

May be it's possible to be done with HList-like types, like: HSet, HVect or
similar, but I don't know:

  - how to iterate/fold over types
  - I'm not sure that HSet/HVect keeps types (like `A ::: B ::: C ::: ...`)

My idea is to have some function which can parse string into one of A|B|C|...
with call like:

  myParse "some-string" :: (Something A ::: B ::: C ::: D)

(suppose `:::` is type-level "cons"). So, `myParse` is polymorphic and
it can fold/iterate over type-list items (to call appropriate
`readPrec`).

Is it even possible?

In languages with reflection I can pass list of types (type - is usual
value) and call type's methods, but how to solve similar in Haskell?

===
Best regards, Paul
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Baa
Reply | Threaded
Open this post in threaded view
|

Re: How to parse hetero-list

Baa
Hmm, I done it with:

  infixl 9 |||
  data a ||| b = A a|B b deriving Show


  instance (Read a, Read b) => Read (a ||| b) where
    readPrec = parens $ do
      a <- (A <$> readPrec) <|> (B <$> readPrec)
      return a

so parse looks like:

  read "1" :: Int ||| Char ||| String

but I'm not sure is other more classical way to do it...


> Hello, All!
>
> I have types A, B, C... They have instances of class Read, Show,
> SomethingElse, ... I want to keep them as one collection. For example,
> I can use such datatype for it:
>
>   data Tags = forall a. Read a => Tags [a]
>
> Now I want to parse "some-string" into A or B or C or ... but without
> to create type's sum of A|B|C|...! All those types have `Read`
> instance but Haskell will not find what instance to use, right? How
> to parse string with alternatives where each alternative returns
> `ReadP A` or `ReadP B`, etc? My intuition is that I should make `x
> <|> y <|> z <|> ...` where x,y,z - parses string into A, B, C, ... so
> they are expressions like `readPrec :: ReadPrec A`, etc. But how to
> pass types into such expression? I must to make expression folding
> (with `<|>`) `readPrec::someType`, where `someType` is item of types
> list `{A, B, C, ...}`
>
> May be it's possible to be done with HList-like types, like: HSet,
> HVect or similar, but I don't know:
>
>   - how to iterate/fold over types
>   - I'm not sure that HSet/HVect keeps types (like `A ::: B :::
> C ::: ...`)
>
> My idea is to have some function which can parse string into one of
> A|B|C|... with call like:
>
>   myParse "some-string" :: (Something A ::: B ::: C ::: D)
>
> (suppose `:::` is type-level "cons"). So, `myParse` is polymorphic and
> it can fold/iterate over type-list items (to call appropriate
> `readPrec`).
>
> Is it even possible?
>
> In languages with reflection I can pass list of types (type - is usual
> value) and call type's methods, but how to solve similar in Haskell?
>
> ===
> Best regards, Paul

_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners