Alternative instance for Get does not respect identity law in error situations
- Ngôn ngữ chính
- Haskell
- Star
- 120
- Fork
- 70
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Mô tả
Hello,
While trying to combine `Get` parsers using `asum`, I found out that `instance Alternative Get` is not lawful: `x <|> empty` is not the same as `x` with respect to failure. `x <|> empty` errors with `"Data.Binary.Get(Alternative).empty"`, overriding the error message from `x`.
For me, an unfortunate consequence is that the implementation of `asum` leaks through: `asum [x, y] = x <|> y <|> empty` provides less helpful parse errors than `x <|> y`.
I have attached a minimal working example, also hosted on this Gist: https://gist.github.com/sugarbleat/4f30751feedf8d3e06911deae7ef4a5a, which can be run with `cabal run Main.hs`. For reference, a similar test with Parsec shows no violation of identity.
Thanks for the great work on the library, by the way!
```haskell
#!/usr/bin/env cabal
{- cabal:
build-depends: base ^>= 4.15
, bytestring ^>= 0.10.12
, binary == 0.8.9.1
-}
module Main (main) where
import Control.Applicative (Alternative (..))
import Data.Binary (Get, Word8, get)
import Data.Binary.Get (runGetOrFail)
import qualified Data.ByteString.Lazy as B
import Data.Foldable (asum)
testGet :: Show a => Get a -> B.ByteString -> IO ()
testGet p s = do
putStrLn "p"
print $ runGetOrFail p s
putStrLn "p <|> empty"
print $ runGetOrFail (p <|> empty) s
putStrLn "asum [p]"
print $ runGetOrFail (asum [p]) s
main :: IO ()
main = testGet (get :: Get Word8) B.empty
{-
Output:
p
Left ("",0,"not enough bytes")
p <|> empty
Left ("",0,"Data.Binary.Get(Alternative).empty")
asum [p]
Left ("",0,"Data.Binary.Get(Alternative).empty")
-}
```
Hướng dẫn đóng góp
Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này
Hướng nghiên cứu
Bắt đầu với ví dụ tối giản trong Main.hs và chạy nó bằng `cabal run Main.hs`, tập trung vào `Alternative Get` và các kết quả của `runGetOrFail`. Được xem là hoàn thành khi `p <|> empty` giữ nguyên lỗi của `p`, và `asum [p]` không còn thay thế lỗi đó bằng lỗi của `empty`.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Đánh giá
- Công nghệ
- haskell
- Lĩnh vực
- backend
- Loại issue
- Lỗi
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức độ hoạt động
- Đình trệ
- Độ rõ ràng
- Khá rõ ràng
- Mức phù hợp với người mới
- 42/100