QuickCheck limit to only certain data constructor - haskell

I have a data type definition:
data Point = Point {x :: Int, h :: Int} | EmptyPoint
In my property test, I would like to limit the test only on the Point constructor cases. For example point1 - point2 = Point 0 0. This presumes that the accessor x is defined which is not the case with EmptyPoint.
in other words: I don't want EmptyPoint to be generated.
Is there a way to do that?

Instead of automatically deriving the Arbitrary class for your type (which is what, I assume, you're doing at the moment), you can just write one manually and make it generate your points however you want, for example:
instance Arbitrary Point where
arbitrary = Point <$> arbitrary <*> arbitrary
Or in a slightly more verbose way if you like:
instance Arbitrary Point where
arbitrary = do
x <- arbitrary
y <- arbitrary
pure Point { x, y }

Related

In Haskell how can I override the (==) and (/=) operators for a type class?

Say I have something like this
class Circle c where
x :: c -> Float
y :: c -> Float
radius :: c -> Float
data Location = Location { locationX :: Float
, locationY :: Float
} deriving (Show, Eq)
data Blob = Location { blobX :: Float
, blobY :: Float
, blobRadius :: Float,
, blobRating :: Int
} deriving (Show, Eq)
instance Circle Location where
x = locationX
y = locationY
radius = pure 0
instance Circle Blob where
x = blobX
y = blobY
radius = blobRadius
Say for example I want Circle types to be equal if their x and y points are equal. How can I compare instances of the type class with the (==) and (/=) operators. I know I can do something like this, but is it possible to overload the operators?
equal :: Circle a => Circle b => a -> b -> Bool
equal a b = (x a == x b && y a == y b)
I want to be able to compare with
(Location 5.0 5.0) == (Blob 5.0 5.0 ... ) should give me True
Zeroth, some standard imports:
import Data.Function (on)
import Control.Arrow ((&&&))
First, this is not a good idea. a==b should only be true if a and b are (for all purposes relevant to the user) interchangeable – that's clearly not the case for two circles which merely happen to share the same center point!
Second, it's probably not a good idea to make Circle a typeclass in the first place. A typeclass only makes sense when you want to abstract over something that can't directly be expressed with just a parameter. But if you just want to attach different “payloads” to points in space, a more sensible approach might be to define something like
data Located a = Located {x,y :: ℝ, payload :: a}
If, as seems to be the case, you actually want to allow different instances of Circle to coexist and be comparable at runtime, then a typeclass is entirely the wrong choice. That would be an OO class. Haskell doesn't have any built-in notion of those, but you could just use
data Blob = Blob
{ x,y :: ℝ
, radius :: ℝ
, rating :: Maybe Int }
and no other types.
https://lukepalmer.wordpress.com/2010/01/24/haskell-antipattern-existential-typeclass/
Third, the instance that you asked for can, theoretically speaking, be defined as
instance (Circle a) => Eq a where
(==) = (==)`on`(x &&& y)
But this would be a truely horrible idea. It would be a catch-all instance: whenever you compare anything, the compiler would check “is it of the form a?” (literally anything is of that form) “oh great, then said instance tells me how to compare this.” Only later would it look at the Circle requirement.
The correct solution is to not define any such Eq instance at all. Your types already have Eq instances individually, that should generally be the right thing to use – no need to express it through the Circle class at all, just give any function which needs to do such comparisons the constraint (Circle a, Eq a) => ....
Of course, these instances would then not just compare the location but the entire data, which, as I said, is a good thing. If you actually want to compare only part of the structure, well, make that explicit! Use not == itself, but extract the relevant parts and compare those. A useful helper for this could be
location :: Circle a => a -> Location
location c = Location (x c) (y c)
...then you can, for any Circle type, simply write (==)`on`location instead of (==), to disregard any other information except the location. Or write out (==)`on`(x &&& y) directly, which can easily be tweaked to other situations.
Two circles that share a common center aren't necessarily equal, but they are concentric; that's what you should write a function to check.
concentric :: (Circle a, Circle b) => a -> b -> Bool
concentric c1 c2 = x c1 == x c2 && y c1 == y c2

How can I perform a scatter/gather operation on types in Haskell?

I have tree that hold contains nodes of different types. These are tagged using a datatype:
data Wrapping = A Int
| B String
I want to write two functions:
scatter :: Wrapping -> a
gather :: a -> Output
The idea is that I can use (scatter.gather) :: Wrapping -> Output. There will of course be several different variations on both the scatter and the gather function (with each scatter variant having a unique Wrappingn datatype, but the set of intermediate types will always be the same) and I want to be able to cleanly compose them.
The issue that I have is that the type parameter a is not really free, it is a small explicit set of types (here it is {Int,String}). If I try to encode what I have so far into Haskell typeclasses then I get to:
{-# LANGUAGE FlexibleInstances #-}
data Wrapping = A Int | B String
class Fanin a where
gather :: a -> String
instance Fanin Int where
gather x = show x
instance Fanin String where
gather x = x
class Fanout a where
scatter :: Fanout a => Wrapping -> a
instance Fanout Int where
scatter (A n) = n
instance Fanout String where
scatter (B x) = x
combined = gather.scatter
The two classes typecheck fine but obviously the final line throws errors because ghc knows that the type parameters do match on every case, only on the two that I have defined. I've tried various combinations of extending one class from the other:
class Fanin a => Fanout a where ...
class Fanout a => Fanin a where ...
Finally I've looked at GADTs and existential types to solve this but I am stumbling around in the dark. I can't find a way to express a legal qualified type signature to GHC, where I've tried combinations of:
{-# LANGUAGE RankNTypes #-}
class (forall a. Fanout a) => Fanin a where
class (forall a. Fanin a) => Fanout a where
Question: how do I express to GHC that I want to restrict a to only the two types in the set?
I get the feeling that the solution lies in one of the techniques that I've looked at but I'm too lost to see what it is...
The idea is that I can use (scatter.gather) :: Wrapping -> Output.
There will of course be several different variations on both the
scatter and the gather function (with each scatter variant having a
unique Wrappingn datatype, but the set of intermediate types will
always be the same) and I want to be able to cleanly compose them.
If I understand correctly, you'd like to have different Wrapping types but the intermediate a type is constantly Either Int String. We can just reflect this information in our classes:
data Wrapping = A Int
| B String
class Fanout wrap where
scatter :: wrap -> Either Int String
instance Fanout Wrapping where
scatter (A n) = Left n
scatter (B str) = Right str
class Fanin output where
gather :: Either Int String -> output
instance Fanin String where
gather = either show id
combined :: Wrapping -> String
combined = gather . scatter
Also, this use case doesn't seem especially amenable to type classes, from what I can glean from the question. In particular, we can get rid of Fanin, and then combined = either show id . scatter looks better to my eyes than the previous definition.
The type class solution makes sense here only if just a single Either Int String -> a or a -> Either Int String function makes sense for each a, and you'd like to enforce this.
If I understand you correctly you need something like the following:
module Main ( main ) where
-- Different kinds of wrapper data types
data WrapperA = A Int | B String
data WrapperB = C Int | D Float
-- A single intermediate data type (with phantom type)
data Intermediate a = E Int | F String
-- Generic scatter and gather functions
class Wrapped a where
scatter :: Wrapped a => a -> Intermediate a
gather :: Wrapped a => Intermediate a -> String
-- Specific scatter and gather implementations
instance Wrapped WrapperA where
scatter (A i) = E i
scatter (B s) = F s
gather (E i) = show i
gather (F s) = s
instance Wrapped WrapperB where
scatter (C i) = E i
scatter (D f) = F $ show f
gather (E i) = show i
gather (F s) = s ++ " was a float"
-- Beautiful composability
combined :: Wrapped a => a -> String
combined = gather . scatter
wrapperAexample1 = A 10
wrapperAexample2 = B "testing"
wrapperBexample1 = C 11
wrapperBexample2 = D 12.4
main :: IO ()
main = do print $ combined wrapperAexample1
print $ combined wrapperAexample2
print $ combined wrapperBexample1
print $ combined wrapperBexample2
The main issue seems to be that you have an intermediate type which can have different kinds of content, but this is constant for different wrappers. Still, depending on the kind of wrapper, you want the gather function to behave differently.
To do this, I would define the Intermediate type to specify the kinds of values that can be held in the intermediate stage, and give it a phantom type parameter (to remember what kind of wrapper it originated from). You can then define a class to hold the scatter and gather functions, and define these differently for different kinds of wrappers.
The code above compiles without errors for me, and gives the following output:
"10"
"testing"
"11"
"12.4 was a float"
As you can see, the WrapperB/D Float input is treated differently than the WrapperA/B String (it is tagged as a float value, even after it has been converted to a String). This is because in the Intermediate representation it is remembered that the origin is a WrapperB: the one is of type Intermediate WrapperA, the other of Intermediate WrapperB.
If, on the other hand, you don't actually want the gather function to behave differently for different wrappers, you can simply take that out of the class and take out the phantom type. The easiest way to let ghc know that the type in the intermediate stage can be Int or String seems to me to still define something like the Intermediate type, rather than use just a.

create an arbitrary intance of "type"

I have the following,
type Pos = (Int, Int)
I want to generate random values of this type with some restrictions (both has to be 0-8)
I would like to do something like
instance Arbitrary Pos where
arbitrary = do x <- choose(0,8)
y <- choose(0,8)
return (x,y)
and then use it in my test to have valid positions.
This won't work bc I'm aliasing(?) tuples
other methods I have tried are to use implications in my test to say
prop_my_prop (x,y) = abs x < 9 && abs y < 9 ==> ...
but I think that's pretty ugly and in theory it might exhaust the quickchecktest (run over 1000 times).
this is an assignment so I just want some indication were to look or how to approach this, I'm not allowed to change Pos.
This won't work bc I'm aliasing(?) tuples
Yes, that's correct. Define a new data type and you can have a new instance.
data Pos = Pos Int Int
or
newtype Pos = Pos (Int, Int)
Then you can write your own Arbitrary instance with whatever generator you like.
Well, if you can't change Pos to a data or newtype for whatever reason, you could always do the following: define a wrapper
newtype PosA = PosA { unPosA :: Pos } deriving (Eq,Show) -- and whatever else you need!
along with an Arbitrary instance for it:
instance Arbitrary PosA where
arbitrary = do x <- choose(0,8)
y <- choose(0,8)
return $ PosA (x,y)
and finally, rewrite all the propositions you want to check so that their type no longer mentions Pos but only PosA instead. Say for example that you had a function mirror and the property that mirroring twice is the identity:
mirror :: Pos -> Pos
mirror (x,y) = (y,x)
prop_mirror :: Pos -> Bool
prop_mirror pos = mirror (mirror pos) == pos
Then you'd need to make prop_mirror_A, something like this (untested code!)
prop_mirror_A :: PosA -> Bool
prop_mirror_A pos = prop_mirror (unPosA pos)
and you're off to the races. You can probably do some of the work 'lifting' from prop_mirror to prop_mirror_A by Clever Typeclass Wizardry, but I'm not going to think about that now :-)
(Incidentally, this is a good reason why type synonyms are usually not the right choice!)
Don Stewart's answer describes the arguably best way to do it. However, if for some reason you don't want to use a newtype you can use a custom generator as follows:
positionsToTest :: Gen Pos
positionsToTest = do x <- choose (0,8)
y <- choose (0,8)
return (x,y)
prop_myTest = forAll positionsToTest ( \ pos -> myProperty pos )
Runnung quickCheck on prop_myTest should do what you want.

Haskell--Manipulating data within a tuple

I'm attempting to simulate a checkers game using haskell. I am given a 4-tuple named, checkersState, that I would like to manipulate with a few different functions. So far, I have a function, oneMove, that receives input from checkerState and should return a tuple of the modified data:
The Input Tuple:
(
3600,
"",
[
"----------",
"------r---",
"----------",
"----------",
"---r-r----",
"------r---",
"---w---w-w",
"----------",
"----------",
"------w---"
],
(
49
,
43
)
)
So far I have something similar to below defining my function but am unsure how to access the individual members within the tuple checkerState. This method will take a time, array of captured pieces, board, and move to make, and return a time, array of captured pieces, and board. Currently, I would like to modify the time (INT) in the tuple depending on the state of the board:
onemove :: (Int,[Char],[[Char]],(Int,Int)) -> (Int,[Char],[[Char]])
Thanks in advance!
You can use pattern-matching to pull out the elements, do whatever changes need to be made, and pack them back into a tuple. For example, if you wanted to increment the first value, you could:
onemove (a,b,c,d) = (a + 1,b,c,d)
If you find yourself doing this a lot, you might reconsider using a tuple and instead use a data type:
data CheckersState = CheckersState { time :: Int -- field names are just
, steps :: [Char] -- guesses; change them
, board :: [[Char]] -- to something that
, pos :: (Int, Int) -- makes sense
} deriving (Eq, Read, Show)
Then you can update it with a much more convenient syntax:
onemove state = state { time = time state + 1 }
If you want to stick with tuples and you happen to be using lenses, there’s another easy way to update your tuple:
onemove = over _1 (+1)
Or if you’re using lenses and your own data type (with an appropriately-defined accessor like the one provided), you can do something similar:
_time :: Lens' CheckersState Int
_time f state = (\newTime -> state { time = newTime }) <$> f (time state)
onemove = over _time (+1)
So there’s plenty of fancy ways to do it. But the most general way is to use pattern-matching.
As icktoofay is saying, using tuples is a code smell, and records with named components is way better.
Also, using Char (and String) is a code smell. To repair it, define a data type that precisely describes what you expect in a cell of the board, like data Colour = None | Red | Black, but see next item.
And, using Lists is also a code smell. You actually want something like type Board = Data.Map.Map Pos Colour or Data.Map.Map Pos (Maybe Colour') with data Colour' = Red | Black.
Oh, and Int is also a code smell. You could define newtype Row = Row Int ; newtype Col = Col Int ; type Pos = (Row,Col). Possibly deriving Num for the newtypes, but it's not clear, e.g., you don't want to multiply row numbers. Perhaps deriving (Eq,Ord,Enum) is enough, with Enum you get pred and succ.
(Ah - this Pos is using a tuple, thus it`s smelly? Well, no, 2-tuples is allowed, sometimes.)
You use pattern matching to decompose the tuple into variables.
onemove (i, c, board, (x, y)) = <do something> (i, c, board)
However, you should define a separate data structure for the board to make your intention clear. I don't know what the meaning of the first two values. See: http://learnyouahaskell.com/making-our-own-types-and-typeclasses

Haskell Access Tuple Data Inside List Comprehension

I have defined a custom type as follows:
-- Atom reference number, x coordinate, y coordinate, z coordinate, element symbol,
-- atom name, residue sequence number, amino acid abbreviation
type Atom = (Int, Double, Double, Double, Word8, ByteString, Int, ByteString)
I would like to gather all of the atoms with a certain residue sequence number nm.
This would be nice:
[x | x <- p, d == nm]
where
(_, _, _, _, _, _, d, _) = x
where p is a list of atoms.
However, this does not work because I can not access the variable x outside of the list comprehension, nor can I think of a way to access a specific tuple value from inside the list comprehension.
Is there a tuple method I am missing, or should I be using a different data structure?
I know I could write a recursive function that unpacks and checks every tuple in the list p, but I am actually trying to use this nested inside an already recursive function, so I would rather not need to introduce that complexity.
This works:
[x | (_, _, _, _, _, _, d, _) <- p, d == nm]
However, you should really define your own data type here. A three-element tuple is suspicious; an eight-element tuple is very bad news indeed. Tuples are difficult to work with and less type-safe than data types (if you represent two different kinds of data with two tuples with the same element types, they can be used interchangeably). Here's how I'd write Atom as a record:
data Point3D = Point3D Double Double Double
data Atom = Atom
{ atomRef :: Int
, atomPos :: Point3D
, atomSymbol :: Word8
, atomName :: ByteString
, atomSeqNum :: Int
, atomAcidAbbrev :: ByteString
} deriving (Eq, Show)
(The "atom" prefix is to avoid clashing with the names of fields in other records.)
You can then write the list comprehension as follows:
[x | x <- p, atomSeqNum x == nm]
As a bonus, your definition of Atom becomes self-documenting, and you reap the benefits of increased type safety. Here's how you'd create an Atom using this definition:
myAtom = Atom
{ atomRef = ...
, atomPos = ...
, ... etc. ...
}
By the way, it's probably a good idea to make some of the fields of these types strict, which can be done by putting an exclamation mark before the type of the field; this helps avoid space leaks from unevaluated thunks building up. For instance, since it doesn't make much sense to evaluate a Point3D without also evaluating all its components, I would instead define Point3D as:
data Point3D = Point3D !Double !Double !Double
It would probably be a good idea to make all the fields of Atom strict too, although perhaps not all of them; for example, the ByteString fields should be left non-strict if they're generated by the program, not always accessed and possibly large. On the other hand, if their values are read from a file, then they should probably be made strict.
You should definitely use a different structure. Instead of using a tuple, take a look at records.
data Atom = Atom { reference :: Int
, position :: (Double, Double, Double)
, symbol :: Word8
, name :: ByteString
, residue :: Int
, abbreviation :: ByteString
}
You can then do something like this:
a = Atom ...
a {residue=10} -- this is now a with a residue of 10

Resources