Haskell: Get the monad Get, and also return polymorphism by infinite types

I apologize in advance if the following is based on a misunderstanding on my part. I could not find the answers I needed.

I am implementing a program that reads serialized objects from a file using all the lazy evaluation. I parse the file by first reading it as one Lazy ByteString, and then parsing it with Get Monad. Inside the file there is one point where type descriptors are stored, and another point where data is stored. Typical descriptors tell me how data should be interpreted and what type it ultimately has, and this type can take nested forms; Double or [[Word8]] - two possibilities.

Now the idea of ​​doing this, which I came across (and that sounded incredibly elegant for a short time), is this: if the method (which parses the type descriptor) creates but does not work, get Monad, which can then later be launched with a ByteString that contains the data ?

This will require a method such as:

parseTypeDescriptor :: Get (Get a)

Where a is the same type that the descriptor describes (which means that it can take nested forms). Here are some parts of the code right now:

parseTypeDescriptor :: Get (Get a)
-- first part of the type descriptor is an id (Word8) that implies a type
parseTypeDescriptor = getWord8 >>= go
   where go 0 = return getWord8
         go 1 = return getWord16be
         go 2 = return getWord32be
                 ...
         -- id 5 indicates that the type is an array
         -- this means two more values are coming;
         -- the first indicates the array length, the second its type
         go 5 = do n      <- getWord8
                   action <- parseTypeDescriptor
                   return $ -- TODO --

The type of "action" must be "Get a". What I need - TODO - is to build a value that performs the action n times, puts these values ​​in an array, and puts Get around this array.

Example: if action = getWord16be and n = 2; then TODO should be equivalent to this:

TODO :: Get [a]
TODO = do x <- getWord16be
          y <- getWord16be
          return [x,y]

I have 3 problems with all of this:

  • I don’t know what code in - TODO - does what I want.
  • , root (parseTypeDescriptors) . Get (Get Word8), Get (Get [Word8])
  • , , Top-Level Get,

, , , , .

+4
1

- ( ) - Get A, , . . Haskell98 , :

{-# LANGUAGE GADTs #-}
data GetSomething where
   GetSomething :: Get a -> GetSomething

parseTypeDescriptor :: Get GetSomething
-- first part of the type descriptor is an id (Word8) that implies a type
parseTypeDescriptor = getWord8 >>= go
   where go 0 = return $ GetSomething getWord8
         go 1 = return $ GetSomething getWord16be
         go 2 = return $ GetSomething getWord32be

... , GetSomething , , ( GADT). - , , :

data GetSomething where
   GetSomething :: CommonClass a => Get a -> GetSomething

, -, .

, , , : , , , . Haskell.

, , :

data GetSomething
   = GetW8 (Get Word8)
   | GetW16 (Get Word16)
   | ...
   | GetList [GetSomething]

, , , , , , , .

+5

Source: https://habr.com/ru/post/1648527/


All Articles