purescript-0.15.13: tests/purs/passing/VTAsClassHeads.purs
module Main where
import Prelude
import Data.Array as Array
import Data.Array.NonEmpty as NEA
import Data.Maybe (Maybe(..))
import Data.Either (Either(..), either)
import Data.Foldable (traverse_)
import Data.Traversable (sequence)
import Effect (Effect)
import Effect.Console (log)
class Singleton x where
singleton :: String
instance Singleton Int where
singleton = "int"
instance Singleton String where
singleton = "string"
singletonWorks :: Effect (Maybe String)
singletonWorks = do
let
left = singleton @Int
right = singleton @String
pure if left /= right then Nothing else Just "Singleton failed"
class ConflictingIdent :: Type -> Constraint
class ConflictingIdent a where
-- The `a` in the type below should refer to the `a`
-- introduced by the `forall`, not the class head.
conflictingIdent :: forall a. a -> Int
instance ConflictingIdent String where
conflictingIdent _ = 1
instance ConflictingIdent Int where
conflictingIdent _ = 2
conflictingIdentWorks :: Effect (Maybe String)
conflictingIdentWorks = do
pure if (1 == conflictingIdent @String 4) then Nothing else Just "ConflictingIdent failed"
type M :: Type -> Type
type M x = forall a. a -> Int
class ConflictingIdentSynonym :: Type -> Constraint
class ConflictingIdentSynonym a where
-- The `a` in the type below should refer to the `a`
-- introduced by the `forall`, not the class head.
conflictingIdentSynonym :: M a
instance ConflictingIdentSynonym String where
conflictingIdentSynonym _ = 1
instance ConflictingIdentSynonym Int where
conflictingIdentSynonym _ = 2
conflictingIdentSynonymWorks :: Effect (Maybe String)
conflictingIdentSynonymWorks = do
pure if (1 == conflictingIdentSynonym @String 4) then Nothing else Just "ConflictingIdentSynonym failed"
class MultiNoFDs a b where
multiNoFds :: Int
instance MultiNoFDs Int Int where
multiNoFds = 0
instance MultiNoFDs String Int where
multiNoFds = 1
multiNoFdsWorks :: Effect (Maybe String)
multiNoFdsWorks = do
let
left = multiNoFds @Int @Int
right = multiNoFds @String @Int
pure if left /= right then Nothing else Just "MultiNoFDs failed"
class MultiWithFDs a b | a -> b where
multiWithFDs :: Int
instance MultiWithFDs Int Int where
multiWithFDs = 0
instance MultiWithFDs String Int where
multiWithFDs = 1
multiWithFdsWorks :: Effect (Maybe String)
multiWithFdsWorks = do
let
left = multiWithFDs @Int
right = multiWithFDs @String
pure if left /= right then Nothing else Just "MultiWithFds failed"
class MultiWithBidiFDs a b | a -> b, b -> a where
multiWithBidiFDs :: Int
instance MultiWithBidiFDs Int Int where
multiWithBidiFDs = 0
instance MultiWithBidiFDs String String where
multiWithBidiFDs = 1
multiWithBidiFDsLeftWorks :: Effect (Maybe String)
multiWithBidiFDsLeftWorks = do
let
left = multiWithBidiFDs @Int
right = multiWithBidiFDs @String
pure if left /= right then Nothing else Just "MultiWithFds failed"
multiWithBidiFDsRightWorks :: Effect (Maybe String)
multiWithBidiFDsRightWorks = do
let
left = multiWithBidiFDs @_ @Int
right = multiWithBidiFDs @_ @String
pure if left /= right then Nothing else Just "MultiWithFds failed"
class Superclass a where
superClassValue :: a
class Superclass a <= MainClass a where
mainClassInt :: Int
data A2 = A2
derive instance Eq A2
instance Superclass A2 where
superClassValue = A2
instance MainClass A2 where
mainClassInt = 0
data B2 = B2
derive instance Eq B2
instance Superclass B2 where
superClassValue = B2
instance MainClass B2 where
mainClassInt = 3
mainClassWorks :: Effect (Maybe String)
mainClassWorks = do
let
test1 = 0 == mainClassInt @A2
test2 = A2 == superClassValue @A2
pure if test1 && test2 then Nothing else Just "MainClass failed"
class MultiCoveringSets a b c d e f | a b -> c d e f, f e -> a b c d where
noneOfSets :: Int
partialOfABSet :: a -> { c :: c, d :: d }
partialOfFESet :: f -> { c :: c, d :: d }
instance MultiCoveringSets Boolean Boolean String String Int Int where
noneOfSets = 1
partialOfABSet a = { c: if a then "101" else "100", d: "1" }
partialOfFESet f = { c: show f, d: "1" }
instance MultiCoveringSets Int Int String String Boolean Boolean where
noneOfSets = 2
partialOfABSet a = { c: show a, d: "2" }
partialOfFESet f = { c: show f, d: "2" }
multiCoveringSetsWorks :: Effect (Maybe String)
multiCoveringSetsWorks = do
let
test1a = 1 == noneOfSets @Boolean @Boolean
test1b = "101" == (partialOfABSet @Boolean @Boolean true).c
test1c = show 3 == (partialOfFESet @_ @_ @_ @_ @Int @Int 3).c
test2a = 2 == noneOfSets @_ @_ @_ @_ @Boolean @Boolean
test2b = show 20 == (partialOfABSet @_ @_ @_ @_ @Boolean @Boolean 20).c
test2c = show false == (partialOfFESet @_ @_ @_ @_ @Boolean @Boolean false).c
passes = test1a && test1b && test1c && test2a && test2b && test2c
pure if passes then Nothing else Just "MultiCoveringSets failed"
main = do
arr' <- sequence
[ singletonWorks
, conflictingIdentWorks
, conflictingIdentSynonymWorks
, multiNoFdsWorks
, multiWithFdsWorks
, multiWithBidiFDsLeftWorks
, multiWithBidiFDsRightWorks
, mainClassWorks
]
case NEA.fromArray $ Array.catMaybes arr' of
Just errs ->
log $ "Errors..." <> (Array.intercalate "\n" $ NEA.toArray errs)
Nothing ->
log "Done"