-- Example
{-# LANGUAGE TemplateHaskell #-}
import Conjure
import Test.LeanCheck
-- This was inspired by the These datatype from the cathis package.
-- https://hackage.haskell.org/package/cathis
-- This is an extension of the type there with the added Neither constructor.
data These a b = Neither | This a | That b | These a b
deriving (Eq, Ord, Show, Read)
isThis :: These a b -> Bool
isThis (This _) = True
isThis (These _ _) = True
isThis _ = False
fromThis :: These a b -> a
fromThis (This x) = x
fromThis (These x _) = x
isThat :: These a b -> Bool
isThat (That _) = True
isThat (These _ _) = True
isThat _ = False
fromThat :: These a b -> b
fromThat (That y) = y
fromThat (These _ y) = y
deriveConjurable ''These
fromThese' :: A -> B -> These A B -> (A, B)
fromThese' 0 1 Neither = (0, 1)
fromThese' 0 1 (This 2) = (2,1)
fromThese' 0 1 (That 2) = (0,2)
fromThese' 0 1 (These 1 0) = (1,0)
listhese' :: These A A -> [A]
listhese' (These 1 2) = [1,2]
listhese' (This 1) = [1]
listhese' (That 2) = [2]
cathis' :: [These A B] -> [A]
cathis' [] = []
cathis' [This 0, This 1] = [0,1]
cathis' [Neither, That 0] = []
cathis' [That 0, This 1] = [1]
cathis' [This 0, Neither, That 1] = [0]
cathis' [This 0, These 0 1] = [0,0]
cathis' [These 0 1, Neither, This 0] = [0,0]
cathis' [These 0 1, This 2] = [0,2]
cathat' :: [These A B] -> [B]
cathat' [] = []
cathat' [This 0, This 1] = []
cathat' [Neither, That 0] = [0]
cathat' [This 0, Neither, That 1] = [1]
cathat' [That 0, These 0 1] = [0,1]
cathat' [These 0 1, That 0] = [1,0]
cathese' :: [These A A] -> [A]
cathese' [] = []
cathese' [This 0, This 1] = [0,1]
cathese' [Neither, That 0] = [0]
cathese' [That 0, This 1] = [0,1]
cathese' [This 0, Neither, That 1] = [0,1]
cathese' [This 0, These 0 1] = [0,0,1]
cathese' [These 0 1, That 2] = [0,1,2]
main :: IO ()
main = do
conjure "fromThese" fromThese'
[ prim "," ((,) :: A -> B -> (A,B))
]
conjure "listhese" listhese'
[ pr ([] :: [A])
, prim ":" ((:) :: A -> [A] -> [A])
]
conjure "cathis" cathis'
[ pr ([] :: [A])
, prim ":" ((:) :: A -> [A] -> [A])
, prim "isThis" (isThis :: These A B -> Bool)
, prim "fromThis" (fromThis :: These A B -> A)
, guard
]
conjure "cathat" cathat'
[ pr ([] :: [B])
, prim ":" ((:) :: B -> [B] -> [B])
, prim "isThat" (isThat :: These A B -> Bool)
, prim "fromThat" (fromThat :: These A B -> B)
, guard
]
conjureWith args{maxPatternDepth = 2} "cathis" cathis'
[ pr ([] :: [A])
, prim ":" ((:) :: A -> [A] -> [A])
]
conjureWith args{maxPatternDepth = 2} "cathat" cathat'
[ pr ([] :: [B])
, prim ":" ((:) :: B -> [B] -> [B])
]
conjureWith args{maxPatternDepth = 2} "cathese" cathese'
[ pr ([] :: [A])
, prim ":" ((:) :: A -> [A] -> [A])
]
-- cathese [] = []
-- cathese (Neither : ts) = cathese ts
-- cathese (This x : ts) = x : these ts
-- cathese (That y : ts) = y : these ts
-- cathese (These x y : ts) = x : y : these ts