Эквивалент сопоставления с шаблоном «двоичного размера (N)» по цепочке битов Elixir / Erlang, в Haskell - PullRequest
0 голосов
/ 23 апреля 2020

Я могу сделать это в эликсире или эрланге:

s = "my binary string"
<<head::binary-size(6), _rest::binary>> = s     
head ===> "my bin"


s2 = <<18, 22, 13, 44, 52, 99>>                  
<<head2::binary-size(4), _rest::binary>> = s2
head2 ===> <<18, 22, 13, 44>>

То есть head и head2 - переменные с интересующими меня результатами.

I я знаком с библиотекой binary Haskell. Я не нашел в ней эквивалентной функциональности - https://hackage.haskell.org/package/binary-0.10.0.0/docs/Data-Binary-Get.html#t: Get

Есть ли способ сделать то же самое в Haskell, особенно в библиотеке binary?

1 Ответ

2 голосов
/ 23 апреля 2020

Эквивалентной функцией в Haskell binary является функция getByteString .

getByteString :: Int -> Get ByteString

getByteString 6 :: Get ByteString

example = runGet (getByteString 6) "my binary string" :: ByteString

. Используйте do-notation для составления Get парсеров. Существует также getRemainingLazyByteString для получения остальной части строки байтов, но имейте в виду, что, хотя это полезно для разбора в стиле Elixir / Erlang, в Haskell композиция синтаксических анализаторов включает большую часть этого:

getThreeBS :: Get (ByteString, ByteString, ByteString)
getThreeBS = do
  x <- getByteString 2
  y <- getByteString 3
  z <- getRemainingLazyByteString
  return (x, y, z)

example1 = runGet getThreeBS "Hello World!"  -- ("He", "llo", " World!")

Другая важная функция: Control.Monad.replicateM:

replicateM :: Int -> Get a -> Get [a]

example2 = runGet (replicateM 5 getWord8) (ByteString.pack [18, 22, 13, 44, 52, 99]) :: [Word8]
...