Quickchecking with a typeclass constraint and reporting the generated values?Have you used Quickcheck in a real projectWhat's new in QuickCheck 2?Find the value that failed for quickcheckWhat is the Comonad typeclass in Haskell?Typeclass constraints on data declarationsQuickCheck: Arbitrary instances of nested data structures that generate balanced specimensHow to generate arbitrary instances of a simple type for quickcheckType Constraints in TypeclassOnly generate positive integers with QuickCheckTypeclass constraint inside typeclass instance

Scaling an object to change its key

I just entered the USA without passport control at Atlanta airport

Would a 7805 5 V regulator drain a 9 V battery?

Story of a Witch Boy

Definition of 'vrit'

What mathematical theory is required for high frequency trading?

First occurrence in the Sixers sequence

Is there a term for the belief that "if it's legal, it's moral"?

Make symbols atomic, without losing their type

reverse a call to mmap()

Implementation of the Jacobi Symbol in C

How can I restore a master database from its bak file?

How can a clan of females defend themselves in the ancient world against wandering bands?

Setting up the trap

How can I ping multiple IP addresses at the same time?

Are there any individual aliens that have gained superpowers in the Marvel universe?

Can the pre-order traversal of two different trees be the same even though they are different?

In a list with unique pairs A, B, how can I sort them so that the last B is the first A in the next pair?

Why is it 出差去 and not 去出差?

King or Queen-Which piece is which?

Why is it easier to balance a non-moving bike standing up than sitting down?

How much steel armor can you wear and still be able to swim?

How can a warlock learn from a spellbook?

I have found ports on my Samsung smart tv running a display service. What can I do with it?



Quickchecking with a typeclass constraint and reporting the generated values?


Have you used Quickcheck in a real projectWhat's new in QuickCheck 2?Find the value that failed for quickcheckWhat is the Comonad typeclass in Haskell?Typeclass constraints on data declarationsQuickCheck: Arbitrary instances of nested data structures that generate balanced specimensHow to generate arbitrary instances of a simple type for quickcheckType Constraints in TypeclassOnly generate positive integers with QuickCheckTypeclass constraint inside typeclass instance






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








2















I'm trying to do a property-based test for a chess game. I have set up the following typeclass



class Monad m => HasCheck m where 
isCollision :: Coord -> m Bool


which checks if a given coordinate contains a collision or out of bounds.



Now I have a function that generates the moveset of allowed actions for a knight like the following



collisionKnightRule :: HasCheck m => Coord -> m (Set Coord) 
collisionKnightRule =
Set.filterM isCollision . knightMoveSet


-- | Set of all moves, legal or not
knightMoveSet :: Coord -> Set Coord
knightMoveSet (x,y) =
Set.fromList
[ (x+2,y-1),(x+2,y+1),(x-2,y-1),(x-2,y+1)
, (x+1,y-2),(x+1,y+2),(x-1,y-2),(x-1,y+2)
]



knightMoves :: HasCheck m => Coord -> m (Set Coord)
knightMoves pos =
do let moveSet =
knightMoveSet pos
invalidMoves <- collisionKnightRule pos
return $ Set.difference moveSet invalidMoves



and an instance for the HasCheck class for an arbitrary coordinate



instance HasCheck Gen where 
isCollision _ =
Quickcheck.arbitrary



and so afterwards to test this I want to ensure that the generated moveset is a proper subset of all possible moves.



knightSetProperty :: Piece.HasCheck Gen 
=> (Int,Int)
-> Gen Bool
knightSetProperty position =
do moves <- Piece.knightMoves position
return $ moves `Set.isProperSubsetOf` (Piece.knightMoveSet position)

-- ... later on

it "Knight ruleset is subset" $
quickCheck knightSetProperty


Of course this fails because it could be that the knight can't move anywhere, which would mean that it's not a proper subset but the same set. However the error reported is not particularly helpful



*** Failed! Falsifiable (after 14 tests and 3 shrinks): 
(0,0)


This is because quickcheck doesn't report the generated value of isCollision. Therefore I wonder, how can I make quickCheck report the generated value of isCollision?










share|improve this question






















  • Why does HasCheck involve a Monad m? Why do you even need that type class? Wouldn't it be simpler to have a pure function isCollision :: Coord -> Bool, without involving a type class?

    – Mark Seemann
    Mar 25 at 11:28











  • For the knight it's not so interesting but the pawn depends on the state of the game and if it has moved before therefore it needs to be a Monad for the State Monad.

    – Marc
    Mar 25 at 19:01












  • Could you write the function as Coord -> State s Bool then? With an unconstrained Monad m, m could also be [], IO, ->, Maybe, and all sorts of other monads. Are any of those meaningful?

    – Mark Seemann
    Mar 25 at 20:51











  • The (->) instance of HasCheck is used for mocking in unit tests. Potentially IO could be interesting too if it's instead requesting a server. The reason I implemented it that way was that I didn't want the logic for the Pieces to concern itself in anyway about how the board is implemented. In theory quickcheck shouldn't need to care about the state of the board either.

    – Marc
    Mar 26 at 3:35












  • One usually doesn't mock in FP; there's no need, because pure functions are already intrinsically testable. Could you design the code so that it's composed of pure functions instead?

    – Mark Seemann
    Mar 26 at 6:45

















2















I'm trying to do a property-based test for a chess game. I have set up the following typeclass



class Monad m => HasCheck m where 
isCollision :: Coord -> m Bool


which checks if a given coordinate contains a collision or out of bounds.



Now I have a function that generates the moveset of allowed actions for a knight like the following



collisionKnightRule :: HasCheck m => Coord -> m (Set Coord) 
collisionKnightRule =
Set.filterM isCollision . knightMoveSet


-- | Set of all moves, legal or not
knightMoveSet :: Coord -> Set Coord
knightMoveSet (x,y) =
Set.fromList
[ (x+2,y-1),(x+2,y+1),(x-2,y-1),(x-2,y+1)
, (x+1,y-2),(x+1,y+2),(x-1,y-2),(x-1,y+2)
]



knightMoves :: HasCheck m => Coord -> m (Set Coord)
knightMoves pos =
do let moveSet =
knightMoveSet pos
invalidMoves <- collisionKnightRule pos
return $ Set.difference moveSet invalidMoves



and an instance for the HasCheck class for an arbitrary coordinate



instance HasCheck Gen where 
isCollision _ =
Quickcheck.arbitrary



and so afterwards to test this I want to ensure that the generated moveset is a proper subset of all possible moves.



knightSetProperty :: Piece.HasCheck Gen 
=> (Int,Int)
-> Gen Bool
knightSetProperty position =
do moves <- Piece.knightMoves position
return $ moves `Set.isProperSubsetOf` (Piece.knightMoveSet position)

-- ... later on

it "Knight ruleset is subset" $
quickCheck knightSetProperty


Of course this fails because it could be that the knight can't move anywhere, which would mean that it's not a proper subset but the same set. However the error reported is not particularly helpful



*** Failed! Falsifiable (after 14 tests and 3 shrinks): 
(0,0)


This is because quickcheck doesn't report the generated value of isCollision. Therefore I wonder, how can I make quickCheck report the generated value of isCollision?










share|improve this question






















  • Why does HasCheck involve a Monad m? Why do you even need that type class? Wouldn't it be simpler to have a pure function isCollision :: Coord -> Bool, without involving a type class?

    – Mark Seemann
    Mar 25 at 11:28











  • For the knight it's not so interesting but the pawn depends on the state of the game and if it has moved before therefore it needs to be a Monad for the State Monad.

    – Marc
    Mar 25 at 19:01












  • Could you write the function as Coord -> State s Bool then? With an unconstrained Monad m, m could also be [], IO, ->, Maybe, and all sorts of other monads. Are any of those meaningful?

    – Mark Seemann
    Mar 25 at 20:51











  • The (->) instance of HasCheck is used for mocking in unit tests. Potentially IO could be interesting too if it's instead requesting a server. The reason I implemented it that way was that I didn't want the logic for the Pieces to concern itself in anyway about how the board is implemented. In theory quickcheck shouldn't need to care about the state of the board either.

    – Marc
    Mar 26 at 3:35












  • One usually doesn't mock in FP; there's no need, because pure functions are already intrinsically testable. Could you design the code so that it's composed of pure functions instead?

    – Mark Seemann
    Mar 26 at 6:45













2












2








2








I'm trying to do a property-based test for a chess game. I have set up the following typeclass



class Monad m => HasCheck m where 
isCollision :: Coord -> m Bool


which checks if a given coordinate contains a collision or out of bounds.



Now I have a function that generates the moveset of allowed actions for a knight like the following



collisionKnightRule :: HasCheck m => Coord -> m (Set Coord) 
collisionKnightRule =
Set.filterM isCollision . knightMoveSet


-- | Set of all moves, legal or not
knightMoveSet :: Coord -> Set Coord
knightMoveSet (x,y) =
Set.fromList
[ (x+2,y-1),(x+2,y+1),(x-2,y-1),(x-2,y+1)
, (x+1,y-2),(x+1,y+2),(x-1,y-2),(x-1,y+2)
]



knightMoves :: HasCheck m => Coord -> m (Set Coord)
knightMoves pos =
do let moveSet =
knightMoveSet pos
invalidMoves <- collisionKnightRule pos
return $ Set.difference moveSet invalidMoves



and an instance for the HasCheck class for an arbitrary coordinate



instance HasCheck Gen where 
isCollision _ =
Quickcheck.arbitrary



and so afterwards to test this I want to ensure that the generated moveset is a proper subset of all possible moves.



knightSetProperty :: Piece.HasCheck Gen 
=> (Int,Int)
-> Gen Bool
knightSetProperty position =
do moves <- Piece.knightMoves position
return $ moves `Set.isProperSubsetOf` (Piece.knightMoveSet position)

-- ... later on

it "Knight ruleset is subset" $
quickCheck knightSetProperty


Of course this fails because it could be that the knight can't move anywhere, which would mean that it's not a proper subset but the same set. However the error reported is not particularly helpful



*** Failed! Falsifiable (after 14 tests and 3 shrinks): 
(0,0)


This is because quickcheck doesn't report the generated value of isCollision. Therefore I wonder, how can I make quickCheck report the generated value of isCollision?










share|improve this question














I'm trying to do a property-based test for a chess game. I have set up the following typeclass



class Monad m => HasCheck m where 
isCollision :: Coord -> m Bool


which checks if a given coordinate contains a collision or out of bounds.



Now I have a function that generates the moveset of allowed actions for a knight like the following



collisionKnightRule :: HasCheck m => Coord -> m (Set Coord) 
collisionKnightRule =
Set.filterM isCollision . knightMoveSet


-- | Set of all moves, legal or not
knightMoveSet :: Coord -> Set Coord
knightMoveSet (x,y) =
Set.fromList
[ (x+2,y-1),(x+2,y+1),(x-2,y-1),(x-2,y+1)
, (x+1,y-2),(x+1,y+2),(x-1,y-2),(x-1,y+2)
]



knightMoves :: HasCheck m => Coord -> m (Set Coord)
knightMoves pos =
do let moveSet =
knightMoveSet pos
invalidMoves <- collisionKnightRule pos
return $ Set.difference moveSet invalidMoves



and an instance for the HasCheck class for an arbitrary coordinate



instance HasCheck Gen where 
isCollision _ =
Quickcheck.arbitrary



and so afterwards to test this I want to ensure that the generated moveset is a proper subset of all possible moves.



knightSetProperty :: Piece.HasCheck Gen 
=> (Int,Int)
-> Gen Bool
knightSetProperty position =
do moves <- Piece.knightMoves position
return $ moves `Set.isProperSubsetOf` (Piece.knightMoveSet position)

-- ... later on

it "Knight ruleset is subset" $
quickCheck knightSetProperty


Of course this fails because it could be that the knight can't move anywhere, which would mean that it's not a proper subset but the same set. However the error reported is not particularly helpful



*** Failed! Falsifiable (after 14 tests and 3 shrinks): 
(0,0)


This is because quickcheck doesn't report the generated value of isCollision. Therefore I wonder, how can I make quickCheck report the generated value of isCollision?







haskell testing typeclass quickcheck






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Mar 25 at 6:05









MarcMarc

877




877












  • Why does HasCheck involve a Monad m? Why do you even need that type class? Wouldn't it be simpler to have a pure function isCollision :: Coord -> Bool, without involving a type class?

    – Mark Seemann
    Mar 25 at 11:28











  • For the knight it's not so interesting but the pawn depends on the state of the game and if it has moved before therefore it needs to be a Monad for the State Monad.

    – Marc
    Mar 25 at 19:01












  • Could you write the function as Coord -> State s Bool then? With an unconstrained Monad m, m could also be [], IO, ->, Maybe, and all sorts of other monads. Are any of those meaningful?

    – Mark Seemann
    Mar 25 at 20:51











  • The (->) instance of HasCheck is used for mocking in unit tests. Potentially IO could be interesting too if it's instead requesting a server. The reason I implemented it that way was that I didn't want the logic for the Pieces to concern itself in anyway about how the board is implemented. In theory quickcheck shouldn't need to care about the state of the board either.

    – Marc
    Mar 26 at 3:35












  • One usually doesn't mock in FP; there's no need, because pure functions are already intrinsically testable. Could you design the code so that it's composed of pure functions instead?

    – Mark Seemann
    Mar 26 at 6:45

















  • Why does HasCheck involve a Monad m? Why do you even need that type class? Wouldn't it be simpler to have a pure function isCollision :: Coord -> Bool, without involving a type class?

    – Mark Seemann
    Mar 25 at 11:28











  • For the knight it's not so interesting but the pawn depends on the state of the game and if it has moved before therefore it needs to be a Monad for the State Monad.

    – Marc
    Mar 25 at 19:01












  • Could you write the function as Coord -> State s Bool then? With an unconstrained Monad m, m could also be [], IO, ->, Maybe, and all sorts of other monads. Are any of those meaningful?

    – Mark Seemann
    Mar 25 at 20:51











  • The (->) instance of HasCheck is used for mocking in unit tests. Potentially IO could be interesting too if it's instead requesting a server. The reason I implemented it that way was that I didn't want the logic for the Pieces to concern itself in anyway about how the board is implemented. In theory quickcheck shouldn't need to care about the state of the board either.

    – Marc
    Mar 26 at 3:35












  • One usually doesn't mock in FP; there's no need, because pure functions are already intrinsically testable. Could you design the code so that it's composed of pure functions instead?

    – Mark Seemann
    Mar 26 at 6:45
















Why does HasCheck involve a Monad m? Why do you even need that type class? Wouldn't it be simpler to have a pure function isCollision :: Coord -> Bool, without involving a type class?

– Mark Seemann
Mar 25 at 11:28





Why does HasCheck involve a Monad m? Why do you even need that type class? Wouldn't it be simpler to have a pure function isCollision :: Coord -> Bool, without involving a type class?

– Mark Seemann
Mar 25 at 11:28













For the knight it's not so interesting but the pawn depends on the state of the game and if it has moved before therefore it needs to be a Monad for the State Monad.

– Marc
Mar 25 at 19:01






For the knight it's not so interesting but the pawn depends on the state of the game and if it has moved before therefore it needs to be a Monad for the State Monad.

– Marc
Mar 25 at 19:01














Could you write the function as Coord -> State s Bool then? With an unconstrained Monad m, m could also be [], IO, ->, Maybe, and all sorts of other monads. Are any of those meaningful?

– Mark Seemann
Mar 25 at 20:51





Could you write the function as Coord -> State s Bool then? With an unconstrained Monad m, m could also be [], IO, ->, Maybe, and all sorts of other monads. Are any of those meaningful?

– Mark Seemann
Mar 25 at 20:51













The (->) instance of HasCheck is used for mocking in unit tests. Potentially IO could be interesting too if it's instead requesting a server. The reason I implemented it that way was that I didn't want the logic for the Pieces to concern itself in anyway about how the board is implemented. In theory quickcheck shouldn't need to care about the state of the board either.

– Marc
Mar 26 at 3:35






The (->) instance of HasCheck is used for mocking in unit tests. Potentially IO could be interesting too if it's instead requesting a server. The reason I implemented it that way was that I didn't want the logic for the Pieces to concern itself in anyway about how the board is implemented. In theory quickcheck shouldn't need to care about the state of the board either.

– Marc
Mar 26 at 3:35














One usually doesn't mock in FP; there's no need, because pure functions are already intrinsically testable. Could you design the code so that it's composed of pure functions instead?

– Mark Seemann
Mar 26 at 6:45





One usually doesn't mock in FP; there's no need, because pure functions are already intrinsically testable. Could you design the code so that it's composed of pure functions instead?

– Mark Seemann
Mar 26 at 6:45












1 Answer
1






active

oldest

votes


















0














Okay so I feel this should be solvable in another way. However I made the following solution that works inspired by the handler pattern.



I changed the HasCheck typeclass to a record, as follows:



data Handle = MakeHandle 
isCollision :: Coord -> Bool




and then refactored all the code to use handle instead of HasCheck.



collisionKnightRule :: Handle -> Coord -> (Set Coord) 
collisionKnightRule handle =
Set.filter (isCollision handle) . knightMoveSet


-- | Set of all moves, legal or not
knightMoveSet :: Coord -> Set Coord
knightMoveSet (x,y) =
Set.fromList
[ (x+2,y-1),(x+2,y+1),(x-2,y-1),(x-2,y+1)
, (x+1,y-2),(x+1,y+2),(x-1,y-2),(x-1,y+2)
]


-- | Set of illegal moves
knightRuleSet :: Handle -> Coord -> (Set Coord)
knightRuleSet =
collisionKnightRule


knightMoves :: Handle -> Coord -> (Set Coord)
knightMoves handle pos =
let
moveSet =
knightMoveSet pos

invalidMoves =
knightRuleSet handle pos
in
Set.difference moveSet invalidMoves


The disadvantage of this is I fear that for stateful code it can be easy to introduce an error where you pass in a handle that is out-of-date, I.E. having multiple sources of truths. An advantage is that this is probably easier for people new to Haskell to understand. We can now mock functions using the Quickcheck's Function typeclass and pass them as an argument to make a mockHandler:



knightSetProperty :: 
Fun (Int,Int) Bool
-> (Int,Int)
-> Gen Bool
knightSetProperty (Fun _ isCollision) position =
let
handler =
Piece.MakeHandle isCollision
moveSet =
Piece.knightMoves handler position
in
return $ moveSet `Set.isProperSubsetOf` (Piece.knightMoveSet position)


Now this fails properly with a counterexample:



*** Failed! Falsifiable (after 53 tests and 74 shrinks): 
_->False
(0,0)





share|improve this answer

























    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55332047%2fquickchecking-with-a-typeclass-constraint-and-reporting-the-generated-values%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    Okay so I feel this should be solvable in another way. However I made the following solution that works inspired by the handler pattern.



    I changed the HasCheck typeclass to a record, as follows:



    data Handle = MakeHandle 
    isCollision :: Coord -> Bool




    and then refactored all the code to use handle instead of HasCheck.



    collisionKnightRule :: Handle -> Coord -> (Set Coord) 
    collisionKnightRule handle =
    Set.filter (isCollision handle) . knightMoveSet


    -- | Set of all moves, legal or not
    knightMoveSet :: Coord -> Set Coord
    knightMoveSet (x,y) =
    Set.fromList
    [ (x+2,y-1),(x+2,y+1),(x-2,y-1),(x-2,y+1)
    , (x+1,y-2),(x+1,y+2),(x-1,y-2),(x-1,y+2)
    ]


    -- | Set of illegal moves
    knightRuleSet :: Handle -> Coord -> (Set Coord)
    knightRuleSet =
    collisionKnightRule


    knightMoves :: Handle -> Coord -> (Set Coord)
    knightMoves handle pos =
    let
    moveSet =
    knightMoveSet pos

    invalidMoves =
    knightRuleSet handle pos
    in
    Set.difference moveSet invalidMoves


    The disadvantage of this is I fear that for stateful code it can be easy to introduce an error where you pass in a handle that is out-of-date, I.E. having multiple sources of truths. An advantage is that this is probably easier for people new to Haskell to understand. We can now mock functions using the Quickcheck's Function typeclass and pass them as an argument to make a mockHandler:



    knightSetProperty :: 
    Fun (Int,Int) Bool
    -> (Int,Int)
    -> Gen Bool
    knightSetProperty (Fun _ isCollision) position =
    let
    handler =
    Piece.MakeHandle isCollision
    moveSet =
    Piece.knightMoves handler position
    in
    return $ moveSet `Set.isProperSubsetOf` (Piece.knightMoveSet position)


    Now this fails properly with a counterexample:



    *** Failed! Falsifiable (after 53 tests and 74 shrinks): 
    _->False
    (0,0)





    share|improve this answer





























      0














      Okay so I feel this should be solvable in another way. However I made the following solution that works inspired by the handler pattern.



      I changed the HasCheck typeclass to a record, as follows:



      data Handle = MakeHandle 
      isCollision :: Coord -> Bool




      and then refactored all the code to use handle instead of HasCheck.



      collisionKnightRule :: Handle -> Coord -> (Set Coord) 
      collisionKnightRule handle =
      Set.filter (isCollision handle) . knightMoveSet


      -- | Set of all moves, legal or not
      knightMoveSet :: Coord -> Set Coord
      knightMoveSet (x,y) =
      Set.fromList
      [ (x+2,y-1),(x+2,y+1),(x-2,y-1),(x-2,y+1)
      , (x+1,y-2),(x+1,y+2),(x-1,y-2),(x-1,y+2)
      ]


      -- | Set of illegal moves
      knightRuleSet :: Handle -> Coord -> (Set Coord)
      knightRuleSet =
      collisionKnightRule


      knightMoves :: Handle -> Coord -> (Set Coord)
      knightMoves handle pos =
      let
      moveSet =
      knightMoveSet pos

      invalidMoves =
      knightRuleSet handle pos
      in
      Set.difference moveSet invalidMoves


      The disadvantage of this is I fear that for stateful code it can be easy to introduce an error where you pass in a handle that is out-of-date, I.E. having multiple sources of truths. An advantage is that this is probably easier for people new to Haskell to understand. We can now mock functions using the Quickcheck's Function typeclass and pass them as an argument to make a mockHandler:



      knightSetProperty :: 
      Fun (Int,Int) Bool
      -> (Int,Int)
      -> Gen Bool
      knightSetProperty (Fun _ isCollision) position =
      let
      handler =
      Piece.MakeHandle isCollision
      moveSet =
      Piece.knightMoves handler position
      in
      return $ moveSet `Set.isProperSubsetOf` (Piece.knightMoveSet position)


      Now this fails properly with a counterexample:



      *** Failed! Falsifiable (after 53 tests and 74 shrinks): 
      _->False
      (0,0)





      share|improve this answer



























        0












        0








        0







        Okay so I feel this should be solvable in another way. However I made the following solution that works inspired by the handler pattern.



        I changed the HasCheck typeclass to a record, as follows:



        data Handle = MakeHandle 
        isCollision :: Coord -> Bool




        and then refactored all the code to use handle instead of HasCheck.



        collisionKnightRule :: Handle -> Coord -> (Set Coord) 
        collisionKnightRule handle =
        Set.filter (isCollision handle) . knightMoveSet


        -- | Set of all moves, legal or not
        knightMoveSet :: Coord -> Set Coord
        knightMoveSet (x,y) =
        Set.fromList
        [ (x+2,y-1),(x+2,y+1),(x-2,y-1),(x-2,y+1)
        , (x+1,y-2),(x+1,y+2),(x-1,y-2),(x-1,y+2)
        ]


        -- | Set of illegal moves
        knightRuleSet :: Handle -> Coord -> (Set Coord)
        knightRuleSet =
        collisionKnightRule


        knightMoves :: Handle -> Coord -> (Set Coord)
        knightMoves handle pos =
        let
        moveSet =
        knightMoveSet pos

        invalidMoves =
        knightRuleSet handle pos
        in
        Set.difference moveSet invalidMoves


        The disadvantage of this is I fear that for stateful code it can be easy to introduce an error where you pass in a handle that is out-of-date, I.E. having multiple sources of truths. An advantage is that this is probably easier for people new to Haskell to understand. We can now mock functions using the Quickcheck's Function typeclass and pass them as an argument to make a mockHandler:



        knightSetProperty :: 
        Fun (Int,Int) Bool
        -> (Int,Int)
        -> Gen Bool
        knightSetProperty (Fun _ isCollision) position =
        let
        handler =
        Piece.MakeHandle isCollision
        moveSet =
        Piece.knightMoves handler position
        in
        return $ moveSet `Set.isProperSubsetOf` (Piece.knightMoveSet position)


        Now this fails properly with a counterexample:



        *** Failed! Falsifiable (after 53 tests and 74 shrinks): 
        _->False
        (0,0)





        share|improve this answer















        Okay so I feel this should be solvable in another way. However I made the following solution that works inspired by the handler pattern.



        I changed the HasCheck typeclass to a record, as follows:



        data Handle = MakeHandle 
        isCollision :: Coord -> Bool




        and then refactored all the code to use handle instead of HasCheck.



        collisionKnightRule :: Handle -> Coord -> (Set Coord) 
        collisionKnightRule handle =
        Set.filter (isCollision handle) . knightMoveSet


        -- | Set of all moves, legal or not
        knightMoveSet :: Coord -> Set Coord
        knightMoveSet (x,y) =
        Set.fromList
        [ (x+2,y-1),(x+2,y+1),(x-2,y-1),(x-2,y+1)
        , (x+1,y-2),(x+1,y+2),(x-1,y-2),(x-1,y+2)
        ]


        -- | Set of illegal moves
        knightRuleSet :: Handle -> Coord -> (Set Coord)
        knightRuleSet =
        collisionKnightRule


        knightMoves :: Handle -> Coord -> (Set Coord)
        knightMoves handle pos =
        let
        moveSet =
        knightMoveSet pos

        invalidMoves =
        knightRuleSet handle pos
        in
        Set.difference moveSet invalidMoves


        The disadvantage of this is I fear that for stateful code it can be easy to introduce an error where you pass in a handle that is out-of-date, I.E. having multiple sources of truths. An advantage is that this is probably easier for people new to Haskell to understand. We can now mock functions using the Quickcheck's Function typeclass and pass them as an argument to make a mockHandler:



        knightSetProperty :: 
        Fun (Int,Int) Bool
        -> (Int,Int)
        -> Gen Bool
        knightSetProperty (Fun _ isCollision) position =
        let
        handler =
        Piece.MakeHandle isCollision
        moveSet =
        Piece.knightMoves handler position
        in
        return $ moveSet `Set.isProperSubsetOf` (Piece.knightMoveSet position)


        Now this fails properly with a counterexample:



        *** Failed! Falsifiable (after 53 tests and 74 shrinks): 
        _->False
        (0,0)






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Mar 27 at 9:00

























        answered Mar 27 at 8:50









        MarcMarc

        877




        877





























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55332047%2fquickchecking-with-a-typeclass-constraint-and-reporting-the-generated-values%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

            Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

            Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript