mkaes
mkaes

Reputation: 14119

How to define own data types as return values in monad function chaining?

I started to play around with haskell and I want to write a parser for binary data that I already did with all programming languages I tried so far.

But I am struggling with the monad concept and a general handling of data in haskell. So far I have the following:

data TestData = T { value :: String } deriving (Show)
data TestData2 = T2 { value2 :: String } deriving (Show)

testFunc :: Handle -> IO BS.ByteString
testFunc hs = BS.hGet hs 4


main = do
            handle <- SIO.openFile "c:/temp/test.bin" SIO.ReadMode
            contents1 <- BS.hGet handle 4
            contents2 <- testFunc handle
            contents3 <- BS.hGet handle 4
            putStrLn (show (T (bytesToString contents1)))
            putStrLn (show (T (bytesToString contents2)))
            putStrLn (show (T (bytesToString contents3)))

The data I want to read are multiple nested structs(spoken i C).
So what I want to know is how to write my testFunc that it will return a data type of my own TestData2 type. But still can be used in the do chain of functions.
Anyone can give me a hint?

Upvotes: 2

Views: 169

Answers (1)

dave4420
dave4420

Reputation: 47052

You can do it this way using do notation:

testFunc :: Handle -> IO TestData2
testFunc hs = do contents <- BS.hGet hs 4
                 return $ T2 (bytesToString contents)

Or you can do it this way using <$> from Control.Applicative:

testFunc :: Handle -> IO TestData2
testFunc hs = T2 . bytesToString <$> BS.hGet hs 4

Upvotes: 2

Related Questions