Help us understand the problem. What is going on with this article?

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

代数的データ型

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);

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

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

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: 良い
  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} => Format.sprintf("#%02X%02X%02X", r, g, 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

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

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, Kotlin: 良い
  3. Haxe, Scala, Dotty, Ruby: 普通
  4. TypeScript, Swift: 書きにくい

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

  1. Rust, Haxe, Swift, Kotlin, Elm, PureScript: パターンを網羅していないとコンパイルエラーになる
  2. Scala, Dotty, OCaml, ReasonML: パターンを網羅していなくても警告するだけでコンパイルが通ってしまう
  3. Koka, Haskell: パターンを網羅していなくても警告なしでコンパイルが通ってしまう
  4. Ruby: 論外
xmeta
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした