Using choose in frequency Haskell QuickCheck - haskell

So I have the code below and I am trying to make it an instance of Arbitrary:
data MyData = I Int | B Bool
instance Arbitrary MyData where
arbitrary = do {
frequency [(1, return (I 1)),
(1, return (choose((B True), (B False))))]
}
With this however I get (understandable) the error:
Couldn't match type ‘Gen MyData’ with ‘MyData’
Expected type: Gen MyData
Actual type: Gen (Gen MyData)
How can I accomplish to implement this? Also instead of (I 1) I would like to return I with a random Int. However using the arbitrary function instead of 1 leads to the same error.

Since you seem to want to distribute evenly between I and B constructors, a simpler solution would be to use oneof instead of frequency:
data MyData = I Int | B Bool deriving (Eq, Show)
instance Arbitrary MyData where
arbitrary = oneof [genI, genB]
where genI = fmap I arbitrary
genB = fmap B arbitrary
The genI and genB generators use the underlying Arbitrary instances of Int and Bool by mapping raw integers and Boolean values to the respective case constructors.
Here's a set of sample data:
> sample (arbitrary :: Gen MyData)
B False
B False
I 2
B False
I 1
I 7
B False
B False
B True
I 7
B False
As you can see, it also accomplishes to pick arbitrary integers.
The code in the OP has several problems. The first error message is that the return type is nested. One way to get around that is to remove the do notation. This, however, doesn't solve the problem.
Even if you reduce it to the following, it doesn't type-check:
instance Arbitrary MyData where
arbitrary =
frequency [(1, return (I 1)),
(1, choose(B True, B False))]
This attempt produces the error:
Q72160684.hs:10:21: error:
* No instance for (random-1.1:System.Random.Random MyData)
arising from a use of `choose'
* In the expression: choose (B True, B False)
In the expression: (1, choose (B True, B False))
In the first argument of `frequency', namely
`[(1, return (I 1)), (1, choose (B True, B False))]'
|
10 | (1, choose(B True, B False))]
| ^^^^^^^^^^^^^^^^^^^^^^^
The choose method requires the input to be Random instances, which MyData isn't.
If you really want to use frequency rather than oneof, the easiest way may be to first get oneof to work, since you can view frequency as a generalisation of oneof.
First, to make the code a little more succinct, I've used <$> instead of fmap and then inlined both generators:
instance Arbitrary MyData where
arbitrary = oneof [I <$> arbitrary, B <$> arbitrary]
Now replace oneof with frequency and change each generator to a weighted tuple:
instance Arbitrary MyData where
arbitrary = frequency [(10, I <$> arbitrary), (1, B <$> arbitrary)]
Sampling from this instance illustrates that the distribution is now skewed:
> sample (arbitrary :: Gen MyData)
I 0
I (-2)
I (-4)
I (-1)
I 0
I 8
B True
I 1
I 3
I (-3)
I (-16)
There are 10 I values and only 1 B value.

You can derive it with generic-random (since 1.5.0.0).
Deriving via GenericArbitraryU: Gives a uniform distribution (like oneof from Mark Seemann's answer):
{-# Language DataKinds #-}
{-# Language DeriveGeneric #-}
{-# Language DerivingVia #-}
import Test.QuickCheck
import GHC.Generics
import Generic.Random.DerivingVia
-- ghci> :set -XTypeApplications
-- ghci> sample #MyData arbitrary
-- I 0
-- I 1
-- B True
-- I 6
-- I (-5)
-- I (-7)
-- B True
-- I (-10)
-- B True
-- B True
-- I (-9)
data MyData = I Int | B Bool
deriving
stock (Show, Generic)
deriving Arbitrary
via GenericArbitraryU MyData
Deriving via GenericArbitrary: gives a weighted distribution specified by a type-level list of numbers. They denote the frequency of each constructor (like frequency):
-- ghci> sample #MyData arbitrary
-- I 0
-- I (-2)
-- I 4
-- I 5
-- I 2
-- I 0
-- B False
-- I (-9)
-- I (-10)
-- I (-3)
-- I (-8)
data MyData = I Int | B Bool
deriving
stock (Show, Generic)
deriving Arbitrary
via GenericArbitrary '[10, 1] MyData

Related

what is the "appropriate value of type `Integer`" and can I write one; also newtypes

Haskell 2010 report section 6.4.1 says
An integer literal represents the application of the function fromInteger to the appropriate value of type Integer.
What does that "appropriate value" look like? Can I write it in source Haskell? I could of course write
x :: Integer
x = 4
But that equation is equivalent to
x = (fromInteger 4) :: Integer
Edit: hmm to avoid infinite regress that should probably be
x = (fromInteger 4?) :: Integer
in which 4? is the mysterious value 4 at type Integer.
so it's selecting the Integer overloading of fromInteger. The type of the literal (in the original x = 4) is still 4 :: Num a => a, it's not type Integer.
I'm thinking about this wrt newtypes:
{-# LANGUAGE GeneralisedNewtypeDeriving #-}
newtype Age = MkAge Int deriving (Num, Eq, Ord, Show)
-- fromInteger is in Num
y :: Age
y = 4
z = (4 + 5 :: Age) -- no decl for z, inferred :: Age
If I ask to show y I see MkAge 4; if I ask to show x I see plain 4. So is there some invisible constructor for Integers?
Supplementary q for newtypes: since I can write z = (4 + 5 :: Age) is the constructor MkAge really necessary?
mkAge2 :: Age -> Age
mkAge2 = id
w = mkAge2 4
mkAge3 :: Integer -> Age
mkAge3 = fromInteger
u = mkAge3 4
seems to work just as well, if I want something prefix.
Can I write it in source Haskell?
Sort of.
You can write 4 :: Integer but 4 is already an application of fromInteger to "an appropriate value". :: Integer only selects an appropriate overload for fromInteger. The application has type Integer though, so it can function like a magic monomorphic literal.
newtype Age = MkAge Int deriving (Num, Eq, Ord, Show)
You can write 4 :: Age now and this is OK. This has nothing to do with what Show does. You can write your own Show instance that prints a plain 4 instead of MkAge 4. This is how Show instances for all the built-in types work. The following is GHC-specific, other implementations may have different details, but the general principles are likely to be the same.
Prelude> :i Int
data Int = GHC.Types.I# Int# -- Defined in ‘GHC.Types’
Prelude> :i Integer
data Integer
= integer-gmp-1.0.2.0:GHC.Integer.Type.S# Int#
| integer-gmp-1.0.2.0:GHC.Integer.Type.Jp# {-# UNPACK #-}integer-gmp-1.0.2.0:GHC.Integer.Type.BigNat
| integer-gmp-1.0.2.0:GHC.Integer.Type.Jn# {-# UNPACK #-}integer-gmp-1.0.2.0:GHC.Integer.Type.BigNat
-- Defined in ‘integer-gmp-1.0.2.0:GHC.Integer.Type’
As you can see, there are data constructors (and they are not that invisible!) for Int and Integer. We can use the one for Int no problem.
Prelude> :set -XMagicHash
Prelude> :t 3#
3# :: GHC.Prim.Int#
Prelude> :t GHC.Types.I# 3#
GHC.Types.I# 3# :: Int
Prelude> show 3
"3"
Prelude> show $ GHC.Types.I# 3#
"3"
OK we have built an Int with a constructor, which doesn't interfere with showing it as a plain 3 one little bit. It is an application of a bona fide constructor to an honest monomorphic literal. What about Integer?
Prelude> GHC.Integer.Type.S# 3#
<interactive>:16:1: error:
Not in scope: data constructor ‘GHC.Integer.Type.S#’
No module named ‘GHC.Integer.Type’ is imported.
Prelude>
Hmm.
Prelude> :m + GHC.Integer.Type
<no location info>: error:
Could not load module ‘GHC.Integer.Type’
it is a hidden module in the package ‘integer-gmp-1.0.2.0’
So Integer constructors are hidden from the programmer (intentionally I suppose). But if you were writing GHC.Integer.Type itself you would be able to use GHC.Integer.Type.S# 3#. This has type Integer and is again an application of a bona fide constructor to an honest monomorphic literal.
4 :: Integer is such a value; 4 :: Int is not. Don't confuse the literal 4 with the family of actual values that it represents in source code.
4 by itself has the polymorphic type Num a => a, which means in the right context, you can "extract" from it a value of type 4 :: Integer. Such a context is a call to fromInteger, since it expects a value of type Integer as an argument, not a value of type Num a => a.
When you write x = 4 after declaring that x is, indeed, a value of type Integer, the compiler takes care of "extracting" the value 4 :: Integer for your from the literal.
MkAge is necessary for type checking. mkAge2 4 works precisely because you have defined (or at least derived) an instance of Num for Age, which entails defining fromInteger :: Integer -> Age. mkAge2 is implicitly calling fromInteger on 4 to return MkAge 4, and that is the value passed to mkAge2. So you still need MkAge, you just don't have to use it explicitly.

`No instance for System.Random.Random` on a custom typeclass when using `choose`

I am doing an exercise in Haskell Programming from First Principles. It asks me to generate equal probabilities, and 1/3, 2/3 probabilities from each of:
data Fool =
Fulse
| Frue
deriving (Eq, Show)
And my answer is
module Random where
-- import Test.Hspec
import Test.QuickCheck
data Fool =
Fulse
| Frue
deriving (Eq, Show)
genFool :: Gen Fool
genFool = choose (Fulse, Frue)
genFool' :: Gen Fool
genFool' = do
frequency [(2, return Fulse)
,(1, return Frue)]
but genFool is wrong. The error message is :
../chap14/random.hs:13:11: error:
• No instance for (System.Random.Random Fool)
arising from a use of ‘choose’
• In the expression: choose (Fulse, Frue)
In an equation for ‘genFool’: genFool = choose (Fulse, Frue)
|
13 | genFool = choose (Fulse, Frue)
| ^^^^^^^^^^^^^^^^^^^^
Previously I have some code like this:
genBool :: Gen Bool
genBool = choose (False, True)
which works properly. I think there may be some predefined instance of System.Random.Random Fool to make the choose work.
What should I do to make the my version of genFool compile?
And btw, why is the return Fulse in the second genFool' of type Gen Fool?
The Test.Quickcheck module's choose function has the following type signature:
choose :: Random a => (a, a) -> Gen a
So, if you are planning to use choose function on your Fool type, it has to be made instance of Random typeclass as seen in the above type signature.
This is where Random typeclass is defined. It needs either a minimal implementation of either randomR and random.
Since your type Fool has only two values, it's isomorphic to Bool type. So, you can define a function mapping the values appropriately:
mapBool :: Bool -> Fool
mapBool False = Fulse
mapBool True = Frue
And then you can define a typeclass instance for your type:
instance Random Fool where
random g = let (b :: Bool, g') = random g
in (mapBool b, g')
randomR _ g = (random g) -- Note that this doesn't work correctly. You need to pattern match and fix this.
The above code should make your module compile fine.

Haskell - create instance of class (how to do it right?)

I read the chapter about that topic in "learn you a haskell" and tried to find some hints on different websites - but are still unable to solve the following task.
Im a haskell newbie (6 weeks of "experience") and its the first time I have to work with instances.
So here is the task, my code has to pass the HUnit tests and the end. I tried to implement the instances but it seems like I´ve missed something there. Hope you can help me! THX
module SemiGroup where
{-
A type class 'SemiGroup' is given. It has exactly one method: a binary operation
called '(<>)'. Also a data type 'Tree' a newtype 'Sum' and a newtype 'Max' are
given. Make them instances of the 'SemiGroup' class.
The 'Tree' instance should build a 'Branch' of the given left and right side.
The 'Sum' instance should take the sum of its given left and right side. You need
a 'Num' constraint for that.
The 'Max' instance should take the maximum of its given left and right side. You
also need a constraint for that but you have to figure out yourself which one.
This module is not going to compile until you add the missing instances.
-}
import Test.HUnit (runTestTT,Test(TestLabel,TestList),(~?=))
-- | A semigroup has a binary operation.
class SemiGroup a where
(<>) :: a -> a -> a
-- Leaf = Blatt, Branch = Ast
-- | A binary tree data type.
data Tree a = Leaf a
| Branch (Tree a) (Tree a)
deriving (Eq,Show)
-- | A newtype for taking the sum.
newtype Sum a = Sum {unSum :: a}
-- | A newtype for taking the maximum.
newtype Max a = Max {unMax :: a}
instance SemiGroup Tree where
(<>) x y = ((x) (y))
instance SemiGroup (Num Sum) where
(<>) x y = x+y
instance SemiGroup (Eq Max) where
(<>) x y = if x>y then x else y
-- | Tests the implementation of the 'SemiGroup' instances.
main :: IO ()
main = do
testresults <- runTestTT tests
print testresults
-- | List of tests for the 'SemiGroup' instances.
tests :: Test
tests = TestLabel "SemiGroupTests" (TestList [
Leaf "Hello" <> Leaf "Friend" ~?= Branch (Leaf "Hello") (Leaf "Friend"),
unSum (Sum 4 <> Sum 8) ~?= 12,
unMax (Max 8 <> Max 4) ~?= 8])
I tried something like:
class SemiGroup a where
(<>) :: a -> a -> a
-- Leaf = Blatt, Branch = Ast
-- | A binary tree data type.
data Tree a = Leaf a
| Branch (Tree a) (Tree a)
deriving (Eq,Show)
-- | A newtype for taking the sum.
newtype Sum a = Sum {unSum :: a}
-- | A newtype for taking the maximum.
newtype Max a = Max {unMax :: a}
instance SemiGroup Tree where
x <> y = Branch x y
instance Num a => SemiGroup (Sum a) where
x <> y = x+y
instance Eq a => SemiGroup (Max a) where
x <> y = if x>y then x else y
But there a still some failures left! At least the wrap/unwrap thing that "chi" mentioned. But I have no idea. maybe another hint ? :/
I fail to see how to turn Tree a into a semigroup (unless it has to be considered up-to something).
For the Sum a newtype, you need to require that a is of class Num. Then, you need to wrap/unwrap the Sum constructor around values so that: 1) you take two Sum a, 2) you convert them into two a, which is a proper type over which + is defined, 3) you sum them, 4) you turn the result back into a Sum a.
You can try to code the above yourself starting from
instance Num a => Semigroup (Sum a) where
x <> y = ... -- Here both x and y have type (Sum a)
The Max a instance will require a similar wrap/unwrap code.
A further hint: to unwrap a Sum a into an a you can use the function
unSum :: Sum a -> a
to wrap an a into a Sum a you can use instead
Sum :: a -> Sum a
Note that both functions Sum, unSum are already implicitly defined by your newtype declaration, so you do not have to define them (you already did).
Alternatively, you can use pattern matching to unwrap your values. Instead of defining
x <> y = ... -- x,y have type Sum a (they are wrapped)
you can write
Sum x <> Sum y = ... -- x,y have type a (they are unwrapped)
Pay attention to the types. Either manually, or with some help from GHCi, figure out the type of the functions you are writing -- you'll find they don't match the types that the typeclass instance needs. You'll use wrapping and unwrapping to adjust the types until they work.

Sort by constructor ignoring (part of) value

Suppose I have
data Foo = A String Int | B Int
I want to take an xs :: [Foo] and sort it such that all the As are at the beginning, sorted by their strings, but with the ints in the order they appeared in the list, and then have all the Bs at the end, in the same order they appeared.
In particular, I want to create a new list containg the first A of each string and the first B.
I did this by defining a function taking Foos to (Int, String)s and using sortBy and groupBy.
Is there a cleaner way to do this? Preferably one that generalizes to at least 10 constructors.
Typeable, maybe? Something else that's nicer?
EDIT: This is used for processing a list of Foos that is used elsewhere. There is already an Ord instance which is the normal ordering.
You can use
sortBy (comparing foo)
where foo is a function that extracts the interesting parts into something comparable (e.g. Ints).
In the example, since you want the As sorted by their Strings, a mapping to Int with the desired properties would be too complicated, so we use a compound target type.
foo (A s _) = (0,s)
foo (B _) = (1,"")
would be a possible helper. This is more or less equivalent to Tikhon Jelvis' suggestion, but it leaves space for the natural Ord instance.
To make it easier to build comparison function for ADTs with large number of constructors, you can map values to their constructor index with SYB:
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Generics
data Foo = A String Int | B Int deriving (Show, Eq, Typeable, Data)
cIndex :: Data a => a -> Int
cIndex = constrIndex . toConstr
Example:
*Main Data.Generics> cIndex $ A "foo" 42
1
*Main Data.Generics> cIndex $ B 0
2
Edit:After re-reading your question, I think the best option is to make Foo an instance of Ord. I do not think there is any way to do this automatically that will act the way you want (just using deriving will create different behavior).
Once Foo is an instance of Ord, you can just use sort from Data.List.
In your exact example, you can do something like this:
data Foo = A String Int | B Int deriving (Eq)
instance Ord Foo where
(A _ _) <= (B _) = True
(A s _) <= (A s' _) = s <= s'
(B _) <= (B _) = True
When something is an instance of Ord, it means the data type has some ordering. Once we know how to order something, we can use a bunch of existing functions (like sort) on it and it will behave how you want. Anything in Ord has to be part of Eq, which is what the deriving (Eq) bit does automatically.
You can also derive Ord. However, the behavior will not be exactly what you want--it will order by all of the fields if it has to (e.g. it will put As with the same string in order by their integers).
Further edit: I was thinking about it some more and realized my solution is probably semantically wrong.
An Ord instance is a statement about your whole data type. For example, I'm saying that Bs are always equal with each other when the derived Eq instance says otherwise.
If the data your representing always behaves like this (that is, Bs are all equal and As with the same string are all equal) then an Ord instance makes sense. Otherwise, you should not actually do this.
However, you can do something almost exactly like this: write your own special compare function (Foo -> Foo -> Ordering) that encapsulates exactly what you want to do then use sortBy. This properly codifies that your particular sorting is special rather than the natural ordering of the data type.
You could use some template haskell to fill in the missing transitive cases. The mkTransitiveLt creates the transitive closure of the given cases (if you order them least to greatest). This gives you a working less-than, which can be turned into a function that returns an Ordering.
{-# LANGUAGE TemplateHaskell #-}
import MkTransitiveLt
import Data.List (sortBy)
data Foo = A String Int | B Int | C | D | E deriving(Show)
cmp a b = $(mkTransitiveLt [|
case (a, b) of
(A _ _, B _) -> True
(B _, C) -> True
(C, D) -> True
(D, E) -> True
(A s _, A s' _) -> s < s'
otherwise -> False|])
lt2Ord f a b =
case (f a b, f b a) of
(True, _) -> LT
(_, True) -> GT
otherwise -> EQ
main = print $ sortBy (lt2Ord cmp) [A "Z" 1, A "A" 1, B 1, A "A" 0, C]
Generates:
[A "A" 1,A "A" 0,A "Z" 1,B 1,C]
mkTransitiveLt must be defined in a separate module:
module MkTransitiveLt (mkTransitiveLt)
where
import Language.Haskell.TH
mkTransitiveLt :: ExpQ -> ExpQ
mkTransitiveLt eq = do
CaseE e ms <- eq
return . CaseE e . reverse . foldl go [] $ ms
where
go ms m#(Match (TupP [a, b]) body decls) = (m:ms) ++
[Match (TupP [x, b]) body decls | Match (TupP [x, y]) _ _ <- ms, y == a]
go ms m = m:ms

How do I make a Record Type bit addressable in Haskell?

I have a record type that is 4 Word32.
data MyType = MyType {a :: Word32, b :: Word32, c :: Word32, d :: Word32 }
Most of the time, I want to treat this type as 4 separate Word32. However, sometimes I wish to treat it as a single stream of binary data (128 bits long, the concatenation of the 4 Word32). I know that in Python, I would write different accessor functions for this "structure", so that I could read/modify it in both ways. But this is Haskell. I am wondering how an experienced Haskeller would go about this?
There's a class for that :-)
import Data.Bits
newtype MyWord128 = MyWord128 MyType
instance Num MyWord128 where
-- implement this one
instance Bits MyWord128 where
-- and then this one, which is what you really want
Check out the documentation for Data.Bits. A complete minimal definition is to provide an implementation of .&., .|., complement, shift, rotate, bitSize and isSigned (or a few other possible combinations: see the doc for details). Annoyingly you also have to implement Num, although it's not entirely clear to me why they defined it that way.
If you really want it to be like a struct of four word32's, you might want to use strict/unpacked fields:
data MyType = MyType { a :: {-# UNPACK #-} !Word32
, b :: {-# UNPACK #-} !Word32
, c :: {-# UNPACK #-} !Word32
, d :: {-# UNPACK #-} !Word32 }
deriving (Show)
Then, let's define a couple of bit-fiddling functions:
mask :: Bits a => Int -> a
mask count = (1 `shiftL` count) - 1
bitRange :: Bits a => Int -> Int -> a -> a
bitRange low count val = (val `shiftR` low) .&. mask count
Now you can just write 128-bit accessors for this type:
from128 :: Integer -> MyType
from128 val = MyType (bitsFrom 0)
(bitsFrom 32)
(bitsFrom 64)
(bitsFrom 96)
where
bitsFrom i = fromIntegral (bitRange i 32 val)
to128 :: MyType -> Integer
to128 (MyType a b c d) =
foldl' (.|.) 0 [
bitsTo a 0,
bitsTo b 32,
bitsTo c 64,
bitsTo d 96
]
where
bitsTo val i = fromIntegral val `shiftL` i
For the a b c d fields, you can just use fclabels. You can also make an fclabel bijective Functor (:<->:):
myType128 :: MyType :<->: Integer
myType128 = to128 :<->: from128

Resources