LoginSignup
87
49

More than 1 year has passed since last update.

代数的データ型とパターンマッチによる言語比較:Koka,Rust,Haxe,Swift,Elm,PureScript,Haskell,OCaml,ReasonML,ReScript,Kotlin,Scala,Dotty,Ruby,Julia,TypeScript

Last updated at Posted at 2016-04-07

代数的データ型

Koka

type color {
  Red
  Green
  Blue
  Rgb( r : int, g : int, b : int )
}

または

type color {
  Red; Green; Blue; Rgb( r : int, g : int, b : int )
}

Rust

enum Color {
 Red,
 Green,
 Blue,
 Rgb { r: u8, g: u8, b: u8 }
}

Haxe

enum Color {
  Red;
  Green;
  Blue;
  Rgb(r: Int, g: Int, b: Int);
}

Swift

enum Color {
  case Red, Green, Blue, Rgb(r: Int, g: Int, b: Int)
}

Elm

type Color = Red | Green | Blue | Rgb { r: Int, g: Int, b: Int }

PureScript

data Color = Red | Blue | Green | Rgb{ r :: Int, g :: Int, b :: Int }

Haskell

data Color = Red | Green | Blue | Rgb {r :: Int, g :: Int, b :: Int}

OCaml

type rgb = { r: int; g: int; b: int }
type color = Red | Green | Blue | Rgb of rgb

ReasonML

type rgb = { r: int, g: int, b: int };
type color =
  | Red
  | Green
  | Blue
  | Rgb(rgb);

ReScript

type color = Red | Green | Blue | Rgb({r: int, g: int, b: int})

Kotlin

sealed class Color {
    object Red: Color()
    object Green: Color()
    object Blue: Color()
    class Rgb(val r: Int,val  g: Int,val  b: Int): Color()
}

Scala

sealed trait Color

final case object Red extends Color
final case object Green extends Color
final case object Blue extends Color
final case class Rgb(r: Int, g: Int, b: Int) extends Color

Dotty(Scala 3)

enum Color {
  case Red
  case Green
  case Blue
  case Rgb(r: Int, g: Int, b: Int)
}

Julia

@enum ColorBase red blue green
struct Rgb
 r::UInt8
 g::UInt8
 b::UInt8
end
Color = Union{ColorBase,Rgb}

TypeScript

type Color = Red | Green | Blue | Rgb;
const enum ColorKind {
  Red = "Red",
  Green = "Green",
  Blue = "Blue",
  Rgb = "Rgb"
}

interface Red {
    kind: ColorKind.Red;
}

interface Green {
    kind: ColorKind.Green;
}

interface Blue {
    kind: ColorKind.Blue;
}

interface Rgb {
    kind: ColorKind.Rgb;
    r: number;
    g: number;
    b: number;
}

Ruby

module Color
  Red = 1
  Green = 2
  Blue = 3
  Rgb = Struct.new(:r, :g, :b)
end

感想

記法

  1. Koka, Rust, Haxe, Elm: とても良い
  2. Dotty, Swift, PureScript, Haskell, OCaml, ReasonML, ReScript: 良い
  3. Ruby: 普通
  4. Kotlin: 書きにくい
  5. Scala: とても書きにくい

パターンマッチ

Koka

match(color) {
  Red   -> "#FF0000"
  Green -> "#00FF00"
  Blue  -> "#0000FF"
  Rgb(r,g,b) -> "#" + showHex(r,2) + showHex(g,2) + showHex(b,2)
}

view code

Rust

match color {
    Color::Red   => "#FF0000".to_string(),
    Color::Green => "#00FF00".to_string(),
    Color::Blue  => "#0000FF".to_string(),
    Color::Rgb{r, g, b} => format!("#{:02X}{:02X}{:02X}", r, g, b),
}

view code

Haxe

switch( color ) {
  case Red:   "#FF0000";
  case Green: "#00FF00";
  case Blue:  "#0000FF";
  case Rgb(r, g, b): "#"+ StringTools.hex(r,2) + StringTools.hex(g,2) + StringTools.hex(b,2);
}

Swift

switch color {
  case .Red:
    return "#FF0000"
  case .Green:
    return "#00FF00"
  case .Blue:
    return "#0000FF"
  case let .Rgb(r, g, b):
    return String(format:"#%02X%02X%02X", r, g, b)
}

view code

Elm

case color of
    Red   -> "#FF0000"
    Green -> "#00FF00"
    Blue  -> "#0000FF"
    Rgb {r, g, b} -> String.concat ["#", (toHex r), (toHex g), (toHex b)]

PureScript

case color of
  Red   -> "#FF0000"
  Green -> "#00FF00"
  Blue  -> "#0000FF"
  Rgb { r, g, b } -> "#" <> toHex r <>  toHex g <>  toHex b 

view code

Haskell

case color of
    Red   -> "#FF0000"
    Green -> "#00FF00"
    Blue  -> "#0000FF"
    Rgb r g b -> printf "#%02X%02X%02X" r g b

view code

OCaml

match color with
      Red   -> "#FF0000"
    | Green -> "#00FF00"
    | Blue  -> "#0000FF"
    | Rgb {r; g; b} -> Printf.sprintf "#%02X%02X%02X" r g b;;

view code

ReasonML

switch (color) {
| Red => "#FF000"
| Green => "#00FF00"
| Blue => "#0000FF"
| Rgb({r, g, b}) => "#" ++ numToHex(r) ++ numToHex(g) ++ numToHex(b)

view code

ReScript

switch color {
| Red => "#FF000"
| Green => "#00FF00"
| Blue => "#0000FF"
| Rgb({r, g, b}) => "#" ++ numToHex(r) ++ numToHex(g) ++ numToHex(b)
}

view code

Kotlin

when ( color ) {
  Color.Red   -> "#FF0000"
  Color.Green -> "#00FF00"
  Color.Blue  -> "#0000FF"
  is Color.Rgb -> "#%02X%02X%02X".format(color.r, color.g, color.b)
}

view code

Scala

color match {
  case Red   =>"#FF0000"
  case Green =>"#00FF00"
  case Blue  =>"#0000FF"
  case Rgb(r, g, b) => "#%02X%02X%02X".format(r, g, b)
}

view code

Dotty(Scala 3)

color match {
  case Color.Red   => "#FF0000"
  case Color.Green => "#00FF00"
  case Color.Blue  => "#0000FF"
  case Color.Rgb(r, g, b) => "#%02X%02X%02X".format(r, g, b)
}

view code

Julia

if color == red
  return "#FF0000"
elseif color == blue
  return "#00FF00"
elseif color == green
  return "#0000FF"
elseif typeof(color) == Rgb
  hex = (x) -> uppercase(string(x, base=16, pad=2))
  return string("#", hex(color.r), hex(color.g), hex(color.b))
end

view code

TypeScript

switch (color.kind) {
    case ColorKind.Red: return "#FF0000";
    case ColorKind.Green: return "#00FF00";
    case ColorKind.Blue: return "#0000FF";
    case ColorKind.Rgb: return "#" + [color.r, color.g, color.b].map((v) => v.toString(16)).join('').toUpperCase();
    default:
        const _exhaustiveCheck: never = color;
        return _exhaustiveCheck;
}

view code

Ruby

case color
when Color::Red; "#FF000"
when Color::Green; "#00FF00"
when Color::Blue; "#0000FF"
when Color::Rgb; "#%02X%02X%02X" % [color.r, color.g, color.b]
end

view code

感想

記法

  1. Koka, Rust, Elm, PureScript, Haskell: とても良い
  2. OCaml, ReasonML, ReScript, Kotlin: 良い
  3. Haxe, Scala, Dotty, Ruby: 普通
  4. TypeScript, Swift: 書きにくい

コンパイラデフォルト動作

  1. Rust, Haxe, Swift, Kotlin, Elm, PureScript: パターンを網羅していないとコンパイルエラーになる
  2. Scala, Dotty, OCaml, ReasonML, ReScript: パターンを網羅していなくても警告するだけでコンパイルが通ってしまう
  3. Koka, Haskell: パターンを網羅していなくても警告なしでコンパイルが通ってしまう
  4. Ruby: 論外
87
49
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
87
49