Как проверить законы функтора с помощью библиотеки шашек

Как использовать библиотеку checkers для проверки законов функтора простого анализатора?

import Test.QuickCheck
import Test.QuickCheck.Checkers
import Test.QuickCheck.Classes
import qualified Data.ByteString as BS

type Index = Int

newtype Parser a = Parser (BS.ByteString -> Index -> (a, Index))

runParser :: Parser a -> BS.ByteString -> Index -> (a, Index)
runParser (Parser p) = p

instance Functor Parser where
    f `fmap` p = Parser $  \bs i -> 
      let (a, ix) = runParser p bs i
      in (f a, ix)

Думаю, мне нужно использовать функцию функтор из Test.QuickCheck.Classes

Тип:

functor :: forall m a b c. (Functor m, Arbitrary a, Arbitrary b, Arbitrary c, 
           CoArbitrary a, CoArbitrary b, Show (m a), Arbitrary (m a), EqProp (m a), EqProp (m c)) 
           => m (a, b, c) -> TestBatch

Теперь m, вероятно, должен быть моим Functor Parser, поэтому мне нужно что-то вроде

main :: IO ()
main = = quickBatch (functor (Parser (a, b, c))

Но что мне использовать для (a, b, c) ?

Примечание. Я знаю, что быстрый тест QuickTest не является доказательством, и я прочитал обсуждение в Как мне протестировать этот прикладной экземпляр с помощью шашек? (Нет экземпляра для CoArbitrary (проверка e0 [Char])) . Однако, если быстрый тест не пройден, я знаю, что мой экземпляр Functor не работает...

Изменить

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

main :: IO ()
main = quickBatch $ functor (undefined :: Parser (Int, String, Char))

Это дает ошибку: Нет экземпляра для (Show (Parser Int))

В сигнатуре типа functor не упоминается экземпляр Read, поэтому я могу написать

instance Show (Parser a) where
   show (Parser a) = "Parsers cannot be printed"

Это дает новую ошибку:

• No instance for (Arbitrary (Parser Int))
    arising from a use of ‘functor’
• In the second argument of ‘($)’, namely

а мне кажется это более сложная проблема...


person Jogger    schedule 19.11.2017    source источник
comment
бесплатная теорема говорит, что вам просто нужно проверить закон тождества. возможно ли для вас создать экземпляр парсера и посмотреть, соблюдается ли закон идентичности? хотя я не очень разбираюсь в шашках.   -  person Jason Hu    schedule 19.11.2017
comment
Реализация functor гарантирует, что значения a, b и c не имеют значения; важны только их типы (возможно, вместо этого следует использовать прокси-аргумент, но в большинстве случаев это, вероятно, более удобно). Но я не уверен, как вы должны выбирать эти типы.   -  person dfeuer    schedule 19.11.2017