[Haskell-cafe] Advice needed on how to improve some code
Jeff
jeff at datalinktech.com.au
Thu Apr 16 23:06:50 UTC 2015
Thanks Sylvain,
I had a suspicion that Applicative might be applicable ( ;-) )
I like Tom Ellis’ suggestions but I might try this out.
Jeff
> On 16 Apr 2015, at 6:24 pm, Sylvain Henry <hsyl20 at gmail.com> wrote:
>
> I don't think you need to update record fields of a blank record: you
> can create the record using applicative operators instead. Something
> like:
>
> parseDevicePLData :: Bool -> Get PayloadData
> parseDevicePLData hasEv = do
> rawEvId <- if hasEv then getWord8 else return 0 -- I guessed the 0 value
> let evId = toEnum (fromIntegral rawEvId .&. 0x7f)
> let statusFlag = testBit rawEvId 7
> mask <- getWord16be
>
> let parseMaybe e p = if testBit mask (fromEnum e) then Just <$> p
> else return Nothing
>
> DevicePL hasEv statusFlag evId mask
> <$> parseMaybe D.GPS parseDeviceGPSData
> <*> parseMaybe D.GSM parseDeviceGSMData
> <*> parseMaybe D.COT parseDeviceCotData
> <*> ...
>
> parseDevicePL :: Bool -> Get Payload
> parseDevicePL hasEv = do
> ts <- parseTimestamp
> P.Payload "" (Just ts) <$> parseDevicePLData hasEv
>
> Then you can lift these "parsers" into you Parser monad only when you need it.
>
> -- Sylvain
>
> 2015-04-16 8:37 GMT+02:00 Jeff <jeff at datalinktech.com.au>:
>> Thanks Tom, David and Claude for your replies.
>>
>>
>>
>>> On 16 Apr 2015, at 4:03 pm, Tom Ellis <tom-lists-haskell-cafe-2013 at jaguarpaw.co.uk> wrote:
>>>
>>> The first thing you should do is define
>>>
>>> parseDeviceGPSDataOf constructor parser setField =
>>> ( \pl' -> let pld = P.payloadData pl' in
>>> if testBit mdm ( fromEnum constructor )
>>> then
>>> parser >>=
>>> ( \s -> return ( pl' { P.payloadData = setField pld (Just s) } } ) )
>>> else
>>> return pl' )
>>>
>>> and your chain of binds will become
>>>
>>> setgpsData pld = pld { P.gpsData = Just s }
>>> ...
>>>
>>> parseDeviceDataOf D.GPS parseDeviceGPSData setgpsData >>=
>>> parseDeviceDataOf D.GSM parseDeviceDSMData setgsmData >>=
>>> parseDeviceDataOf D.COT parseDeviceCOTData setcotData >>=
>>> ...
>>>
>>> Then I would probably write
>>>
>>> deviceSpecs = [ (D.GPS, parseDeviceGPSData, setgpsData)
>>> , (D.GSM, parseDeviceDSMData, setgsmData)
>>> , (D.COT, parseDeviceCOTData, setcotData) ]
>>>
>>> and turn the chain of binds into a fold.
>>>
>>
>>
>> I’ll do as you have suggested Tom. Thanks.
>>
>> Jeff
>>
>> _______________________________________________
>> Haskell-Cafe mailing list
>> Haskell-Cafe at haskell.org
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
More information about the Haskell-Cafe
mailing list