From ebe94e2d9bde0cafc5eaf12b4972dedfd81f6b72 Mon Sep 17 00:00:00 2001 From: VegOwOtenks Date: Fri, 15 Aug 2025 13:03:31 +0200 Subject: [PATCH] feat[core]: Algebraic Data Types --- scalie.cabal | 5 +++++ src/Language/Scalie/Core/AlgebraicDatatype.hs | 19 ++++++++++++++++ .../Core/AlgebraicDatatype/Constructor.hs | 13 +++++++++++ .../Scalie/Core/AlgebraicDatatype/Field.hs | 16 ++++++++++++++ .../Core/AlgebraicDatatype/FieldIdentifier.hs | 8 +++++++ .../Scalie/Core/AlgebraicDatatype/TypeName.hs | 22 +++++++++++++++++++ 6 files changed, 83 insertions(+) create mode 100644 src/Language/Scalie/Core/AlgebraicDatatype.hs create mode 100644 src/Language/Scalie/Core/AlgebraicDatatype/Constructor.hs create mode 100644 src/Language/Scalie/Core/AlgebraicDatatype/Field.hs create mode 100644 src/Language/Scalie/Core/AlgebraicDatatype/FieldIdentifier.hs create mode 100644 src/Language/Scalie/Core/AlgebraicDatatype/TypeName.hs diff --git a/scalie.cabal b/scalie.cabal index bf5a427..5d04b75 100644 --- a/scalie.cabal +++ b/scalie.cabal @@ -24,6 +24,11 @@ library Language.Scalie.Bytecode.Object Language.Scalie.Bytecode.Object.Builder Language.Scalie.Compiler.Bytecode + Language.Scalie.Core.AlgebraicDatatype + Language.Scalie.Core.AlgebraicDatatype.Constructor + Language.Scalie.Core.AlgebraicDatatype.Field + Language.Scalie.Core.AlgebraicDatatype.FieldIdentifier + Language.Scalie.Core.AlgebraicDatatype.TypeName Language.Scalie.Core.Definition Language.Scalie.Core.Expression Language.Scalie.Core.Expression.ConstructorIdentifier diff --git a/src/Language/Scalie/Core/AlgebraicDatatype.hs b/src/Language/Scalie/Core/AlgebraicDatatype.hs new file mode 100644 index 0000000..3b001db --- /dev/null +++ b/src/Language/Scalie/Core/AlgebraicDatatype.hs @@ -0,0 +1,19 @@ +{-# LANGUAGE Trustworthy #-} +module Language.Scalie.Core.AlgebraicDatatype (AlgebraicDatatype(..)) where + +-- meta +import Data.Kind (Type) + +-- data structures +import Data.Vector (Vector) + +-- scalie +import Language.Scalie.Core.AlgebraicDatatype.TypeName (TypeName) +import Language.Scalie.Core.AlgebraicDatatype.Constructor (Constructor) + +type AlgebraicDatatype :: (Type -> Type) -> Type +type role AlgebraicDatatype nominal +data AlgebraicDatatype f = AlgebraicDatatype + { name :: f TypeName + , constructors :: f (Vector (Constructor f)) + } diff --git a/src/Language/Scalie/Core/AlgebraicDatatype/Constructor.hs b/src/Language/Scalie/Core/AlgebraicDatatype/Constructor.hs new file mode 100644 index 0000000..e70144c --- /dev/null +++ b/src/Language/Scalie/Core/AlgebraicDatatype/Constructor.hs @@ -0,0 +1,13 @@ +{-# LANGUAGE Trustworthy #-} -- uses vector operations +module Language.Scalie.Core.AlgebraicDatatype.Constructor (Constructor(..)) where +import Data.Kind (Type) +import Language.Scalie.Core.Expression.ConstructorIdentifier (ConstructorIdentifier) +import Data.Vector (Vector) +import Language.Scalie.Core.AlgebraicDatatype.Field (Field) + +type Constructor :: (Type -> Type) -> Type +type role Constructor nominal +data Constructor f = Constructor + { name :: f ConstructorIdentifier + , fields :: f (Vector (Field f)) + } diff --git a/src/Language/Scalie/Core/AlgebraicDatatype/Field.hs b/src/Language/Scalie/Core/AlgebraicDatatype/Field.hs new file mode 100644 index 0000000..808b4b8 --- /dev/null +++ b/src/Language/Scalie/Core/AlgebraicDatatype/Field.hs @@ -0,0 +1,16 @@ +{-# LANGUAGE Safe #-} +module Language.Scalie.Core.AlgebraicDatatype.Field (Field(..)) where + +-- meta +import Data.Kind qualified + +-- scalie +import Language.Scalie.Core.AlgebraicDatatype.FieldIdentifier (FieldIdentifier) +import Language.Scalie.Domain.Type qualified as Scalie.Domain + +type Field :: (Data.Kind.Type -> Data.Kind.Type) -> Data.Kind.Type +type role Field nominal +data Field f = Field + { name :: f FieldIdentifier + , typ :: f Scalie.Domain.Type + } diff --git a/src/Language/Scalie/Core/AlgebraicDatatype/FieldIdentifier.hs b/src/Language/Scalie/Core/AlgebraicDatatype/FieldIdentifier.hs new file mode 100644 index 0000000..8892208 --- /dev/null +++ b/src/Language/Scalie/Core/AlgebraicDatatype/FieldIdentifier.hs @@ -0,0 +1,8 @@ +{-# LANGUAGE Safe #-} +module Language.Scalie.Core.AlgebraicDatatype.FieldIdentifier (FieldIdentifier(..)) where +import Data.Text (Text) +import Data.Kind (Type) + +type FieldIdentifier :: Type +newtype FieldIdentifier = FieldIdentifier { get :: Text } + deriving stock (Show, Read, Eq) diff --git a/src/Language/Scalie/Core/AlgebraicDatatype/TypeName.hs b/src/Language/Scalie/Core/AlgebraicDatatype/TypeName.hs new file mode 100644 index 0000000..14d2667 --- /dev/null +++ b/src/Language/Scalie/Core/AlgebraicDatatype/TypeName.hs @@ -0,0 +1,22 @@ +{-# LANGUAGE Safe #-} +{-# LANGUAGE InstanceSigs #-} +module Language.Scalie.Core.AlgebraicDatatype.TypeName (TypeName(..)) where + +-- meta +import Data.Kind (Type) + +-- data structures +import Data.Text (Text) +import Data.Text qualified as Text + +-- library: QuickCheck +import Test.QuickCheck (Arbitrary (arbitrary), Gen, UnicodeString (getUnicodeString)) + +type TypeName :: Type +newtype TypeName = TypeName { get :: Text } + deriving stock (Show, Read, Eq) + +instance Arbitrary TypeName where + arbitrary :: Gen TypeName + arbitrary = TypeName . Text.pack . getUnicodeString <$> arbitrary +