Как использовать библиотеку 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
а мне кажется это более сложная проблема...
functor
гарантирует, что значенияa
,b
иc
не имеют значения; важны только их типы (возможно, вместо этого следует использовать прокси-аргумент, но в большинстве случаев это, вероятно, более удобно). Но я не уверен, как вы должны выбирать эти типы. - person dfeuer   schedule 19.11.2017