Tôi thực sự ghét hỏi loại câu hỏi này nhưng tôi đã kết thúc trí thông minh của mình ở đây. Tôi đang viết một trình phân tích cú pháp gia tăng nhưng vì một lý do nào đó, không thể tìm ra cách thực hiện cá thể functor cho nó. Dưới đây là các bãi chứa mã:Trình phân tích cú pháp gia tăng này có phải là một hàm functor không, nếu như vậy `fmap` sẽ được thực hiện như thế nào?
Input Type liệu
Input là kiểu dữ liệu thu được từ phân tích cú pháp cho coroutine. Nó chứa danh sách hiện tại của ký tự đầu vào được phẫu thuật bởi coroutine và kết thúc của tình trạng dòng
data Input a = S [a] Bool deriving (Show)
instance Functor Input where
fmap g (S as x) = S (g <$> as) x
Loại Data Output
Output là kiểu dữ liệu thu được từ coroutine để Parser. Nó là một trong hai nhắn Không, Done [b], hoặc một phần ([a] -> Output ab), nơi [a] là bộ đệm hiện nay truyền lại cho phân tích cú pháp
data Output a b = Fail String | Done [b] | Partial ([a] -> Output a b)
instance Functor (Output a) where
fmap _ (Fail s) = Fail s
fmap g (Done bs) = Done $ g <$> bs
fmap g (Partial f) = Partial $ \as -> g <$> f as
Các Parser
Các phân tích cú pháp mất [a] và mang lại một bộ đệm [a] để coroutine, trong đó sản lượng trở lại Output ab
data ParserI a b = PP { runPi :: [a] -> (Input a -> Output a b) -> Output a b }
functor thực hiện
Nó có vẻ như tất cả những gì phải làm là fmap chức năng g vào coroutine, như sau:
instance Functor (ParserI a) where
fmap g p = PP $ \as k -> runPi p as (\xs -> fmap g $ k xs)
Nhưng nó không gõ kiểm tra:
Couldn't match type `a1' with `b'
`a1' is a rigid type variable bound by
the type signature for
fmap :: (a1 -> b) -> ParserI a a1 -> ParserI a b
at Tests.hs:723:9
`b' is a rigid type variable bound by
the type signature for
fmap :: (a1 -> b) -> ParserI a a1 -> ParserI a b
at Tests.hs:723:9
Expected type: ParserI a b
Actual type: ParserI a a1
'ParserI' không phải là một hàm. Không có trường hợp nào tồn tại. –
Oh X (Tôi có thể yêu cầu bạn giải thích tại sao? Và làm thế nào tôi có thể cấu trúc lại nó sao cho nó là một functor? Ví dụ trong Attoparsec.Incremental (depreicated), coroutine có kiểu tương tự như (c -> Input a -> Output ab), nhưng tôi không thể tìm ra c là gì cho – chibro2
'fmap gp = PP $ \ như k -> runPi p như (\ xs -> fmap g $ k as)' <- mà cuối cùng 'là' có được dự định là một 'xs', phải không? –