Динамический
объектно-ориентированный язык Haskell

Роман Чепляка
@shebang

Новый тип

data MyInt where
  MkMyInt :: Int -> MyInt

Создание значения

a :: MyInt
a = MkMyInt 42

Pattern matching

extractInt :: MyInt -> Int
extractInt (MkMyInt n) = n

Кортежи

data Employee where
  MkEmployee
    :: String -- name
    -> Int    -- age
    -> Double -- salary
    -> Employee

Объединения

data Shape where
  Circle :: Double {- radius -} -> Shape
  Rectangle :: Double -> Double -> Shape

area :: Shape -> Double
area (Circle r) = pi * r^2
area (Rectangle x y) = x * y

Динамическая типизация

data Value where
  Scalar :: Double -> Value
  String :: String -> Value
  Array  :: Vector Value -> Value
  Dict   :: HashTable Value -> Value
  Func   :: (Value -> Value) -> Value

Статическая vs динамическая типизация

square :: Double -> Double
square x = x^2

x = square "foo" -- compile-time error

vs

square :: Value -> Value
square (Scalar x) = Scalar (x^2)
square _ = throw DynamicTypeException

x = square (String "foo") -- run-time error

Динамические типы в C

enum TAG { SCALAR, STRING, ARRAY, DICT, FUNC };

struct dyn_t {
  enum TAG tag;

  union {
    scalar_t scalar;
    string_t string;
    array_t  array;
    dict_t   dict;
    func_t   func;
  } payload;
};

Статические типы в Perl

sub square($) {
  my $x = shift;
  return $x ** 2;
}

my @y = (1,2);
print square(@y);

Динамические типы в Perl

sub square($) {
  my $x = shift;
  return $$x ** 2;
}

my @y = (1,2);
print square(\@y);

Параметризованные типы

data Value a where
  MkValue :: a -> Value a

a :: Value Int
a = MkValue 42

extractInt :: Value Int -> Int
extractInt (MkValue n) = n

Экзистенциальные типы

data Value   where
  MkValue :: a -> Value

a :: Value
a = MkValue 42

extractInt :: Value     -> Int
extractInt (MkValue n) = n

Экзистенциальные типы

data Value   where
  MkValue :: a -> Value

a :: Value
a = MkValue 42

extractInt :: Value     -> Int
extractInt (MkValue n) = unsafeCoerce n

Динамическая типизация

data Tag where
  IntTag :: Tag
  StringTag :: Tag

data Value where
  MkValue :: Tag -> a -> Value

a :: Value
a = MkValue IntTag 42

extractInt :: Value -> Int
extractInt (MkValue IntTag n) = unsafeCoerce n
extractInt _ = throw DynamicTypeException

Динамическая типизация

data Tag a where
  IntTag :: Tag Int
  StringTag :: Tag String

data Value where
  MkValue :: Tag a -> a -> Value

a :: Value
a = MkValue IntTag 42

extractInt :: Value -> Int
extractInt (MkValue IntTag n) = n
extractInt _ = throw DynamicTypeException

ООП

data Counter where
  MkCounter
    ::  u
    -> (u -> Counter) -- increment
    -> (u -> Int)     -- get value
    -> Counter

ООП

data Set a where
  MkSet
    ::  s
    -> (s -> [a])            -- elements
    -> (s -> Set a -> Set a) -- union
    -> Set a

ООП

data Set a where
  MkSet
    ::  s
    -> (s -> [a])            -- elements
    -> (s -> s -> Set a)     -- union
    -> Set a

АТД

data Set a where
  MkSet
    :: (s -> [a])    -- elements
    -> (s -> s -> s) -- union
    ->  s            -- empty
    -> (a -> s)      -- singleton
    -> Set a

ООП и ленивость

data Iterator a where
  End :: Iterator a
  Focus
    ::  u
    -> (u -> a)          -- current
    -> (u -> Iterator a) -- next
    -> Iterator a

ООП и ленивость

data Iterator a where
  End :: Iterator a
  Focus
    ::  u
    -> (u -> (a, Iterator a))
    -> Iterator a

ООП и ленивость

data Iterator a where
  End :: Iterator a
  Focus
    :: (a, Iterator a)
    -> Iterator a

ООП и ленивость

data Iterator a where
  End :: Iterator a
  Focus
    :: a
    -> Iterator a
    -> Iterator a

ООП и ленивость

data List a where
  Nil :: Iterator a
  Cons
    :: a
    -> List a
    -> List a

Выводы