Skip to content

Instantly share code, notes, and snippets.

@pete-murphy
Created May 10, 2018 12:00
Show Gist options
  • Save pete-murphy/eb9427c904b8442ddd3a5a5eb8bc9059 to your computer and use it in GitHub Desktop.
Save pete-murphy/eb9427c904b8442ddd3a5a5eb8bc9059 to your computer and use it in GitHub Desktop.
Haskell Book 15.15 Exercise 9
{-# LANGUAGE DeriveGeneric #-}
module SemigroupExercises where
import Data.Semigroup
import Test.QuickCheck
import GHC.Generics
-- ...
newtype Combine a b =
Combine { unCombine :: (a -> b) }
deriving (Generic)
instance Semigroup b
=> Semigroup (Combine a b) where
Combine { unCombine = f } <> Combine { unCombine = g } =
Combine { unCombine = (\x -> (f x) <> (g x)) }
-- arbitrary :: Arbitrary a => Gen a
-- coarbitrary :: Coarbitrary a => a -> Gen b -> Gen b
instance (CoArbitrary a, Arbitrary b) => Arbitrary (Combine a b) where
arbitrary = do
f <- arbitrary
-- f <- (arbitrary :: Gen (a -> b))
-- The line above does not work for
-- reasons not entirely clear to me
return $ Combine { unCombine = f }
-- (Cannot get Eq instance to work)
-- instance (Eq b) => Eq (Combine a b) where
-- Combine f == Combine g =
-- unCombine (Combine f) == unCombine (Combine g)
-- This is same as: f == g
-- Which you can't do? (Because decidability problem?)
-- Sure why not
instance Show (Combine a b) where
show (Combine _) = "Combine a b"
-- Not sure why this doesn't work
-- if we've already established an
-- Arbitrary instance for Combine a b
--
prop_combAssoc :: Property
prop_combAssoc =
forAll (arbitrary :: Gen (Combine a b))
$ \f ->
forAll (arbitrary :: Gen (Combine a b))
$ \g ->
forAll (arbitrary :: Gen (Combine a b))
$ \h ->
f <> (g <> h) == (f <> g) <> h
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment