Pregunta

Me gustaría pasar un entero como un CLI argumento a un Haskell programa que hace uso de QuickCheck / monadicIO.Que entero va a ser utilizado en el interior de la assert para realizar las pruebas personalizables.El problema es que una vez que analizar el valor entero en main, No sé cómo pasar dentro de la monadicIO llame sin el uso de algo tan feo como un IORef.Yo creo que una solución elegante podría ser el Reader mónada, pero no pude encontrar una solución para hacer el trabajo, visto como quickCheck es rígido en sus argumentos.Alguna idea?

Más Tarde Edit 1: Conforme a lo solicitado, estoy adjuntando el código real que estoy tratando en este, y en su defecto.La comentada líneas de representar a mi intento fallido.Antecedentes:la suite de prueba es la intención de ejercer una forma muy sencilla extremo remoto que calcula el SHA512 de la aleatorios de entrada generados por QuickCheck.El extremo remoto de Python/Matraz de base.

Después de Editar 2 en respuesta a @user2407038: Yo podría hacer propHasExpectedLengthCeiling tome un argumento de tipo Int, pero quickCheck iba a generar valores aleatorios para ella, y eso no es lo que quiero que suceda.Mi objetivo es utilizar la maxSegmentLengthCeiling que estoy tomando desde los argumentos de línea de comandos y el uso en let testPassed = actualMaxSegmentLength <= maxSegmentLengthCeiling en el interior de la monadicIO el bloque.Ahora mismo maxSegmentLengthCeiling se especifica como un valor de nivel superior, lo que significa que tengo que volver a compilar el código cada vez que cambie el valor.Yo aún no tiene ningún código que implica IORef debido a que es un último recurso y la esencia de mi pregunta es como evitar el IORef de la ruta.

import qualified Data.ByteString.Lazy.Char8 as LC

import Control.Applicative     ( (<$>) )
import Data.Function           ( on )
import Data.List               ( groupBy )
import Data.Char               ( isDigit )
--import Safe                    ( headMay
--                               , readMay
--                               )
--import System.Environment      ( getArgs )
import Network.HTTP.Conduit    ( simpleHttp )
import Test.QuickCheck         ( Arbitrary
                               , Property
                               , arbitrary
                               , choose
                               , frequency
                               , quickCheckWith
                               , stdArgs
                               , vectorOf
                               )
import Test.QuickCheck.Test    ( Args
                               , maxSuccess
                               )
import Test.QuickCheck.Monadic ( assert
                               , monadicIO
                               , run
                               )

newtype CustomInput = MkCustomInput String deriving Show

instance Arbitrary CustomInput where
  arbitrary =
    let
      genCustomInput = vectorOf 20
                       $ frequency [ (26, choose ('0','9'))
                                   , (10, choose ('a','z'))
                                   ]
    in
      MkCustomInput <$> genCustomInput

maxSegmentLengthCeiling :: Int
maxSegmentLengthCeiling = 22

urlPrefix :: String
urlPrefix = "http://192.168.2.3:5000/sha512sum/"

propHasExpectedLengthCeiling :: CustomInput -> Property
propHasExpectedLengthCeiling (MkCustomInput input) = monadicIO $ do
  testPassed <- run $ do
    response <- simpleHttp $ urlPrefix ++ input
    let stringResponse = LC.unpack response
    let brokenDownStringResponse = groupBy ( (==) `on` isDigit ) stringResponse
    let actualMaxSegmentLength = maximum $ map length brokenDownStringResponse
    let testPassed = actualMaxSegmentLength <= maxSegmentLengthCeiling
    putStrLn ""
    putStrLn ""
    putStrLn $ "Input:       " ++ input
    putStrLn $ "Control sum: " ++ stringResponse
    putStrLn $ "Breakdown:   " ++ show brokenDownStringResponse
    putStrLn $ "Max. length: " ++ show actualMaxSegmentLength
    putStrLn $ "Ceiling:     " ++ show maxSegmentLengthCeiling
    putStrLn $ "Test result: " ++ if testPassed then "Pass" else "Fail"
    putStrLn ""
    putStrLn ""
    return testPassed
  assert $ testPassed

customArgs :: Args
customArgs = stdArgs { maxSuccess = 1000000 }

--readMayAsInt :: String -> Maybe Int
--readMayAsInt = readMay

main :: IO ()
main =
--main = do
--  cliArgs <- getArgs
--  let ceilingInputMay = headMay cliArgs >>= readMayAsInt
--  maxSegmentLengthCeiling <- case ceilingInputMay of
--                               (Just lengthCeiling) -> return lengthCeiling
--                               Nothing              -> error "No valid number given"
  quickCheckWith
    customArgs
    propHasExpectedLengthCeiling
¿Fue útil?

Solución

Hacer maxSegmentLengthCeiling un parámetro para propHasExpectedLengthCeiling :

propHasExpectedLengthCeiling :: Int -> CustomInput -> Property

y llámalo como

main = do 
  [n] <- getArgs
  quickCheckWith customArgs (propHasExpectedLengthCeiling (read n))
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top