LoginSignup
2

More than 5 years have passed since last update.

PureScript by Example の 5.12, 5.13, 5.14 を読む

Last updated at Posted at 2016-12-16

この記事は (bouzuya) PureScript Advent Calendar 2016 の 16 日目。 (bouzuya) PureScript Advent Calendar 2016 は bouzuya の PureScript 学習の記録だ。

概要

PureScript by ExamplePureScript Language GuidePursuit を見ながら進めていく。

今日は 5.12 から読んでいく。ソースコードの例は purescript-book の chapter5 にある。

※注意事項: 英語と日本語訳では大きな差異がある。0.10.x に対応している英語の側で進める。

前回のおさらい

この章では代数的データ型 (algebraic data type) とパターンマッチ (pattern matching) および行多相 (row polymorphism) を扱うらしい。

Number String Char Boolean Array Record のパターンマッチを見た。またガード・パターンマッチのネスト・ @ で名前付け・ case 式・部分関数と unsafePartial を見た。

Language Guide:

PureScript by Example 5.12

代数的データ型 (ADT: Algebraic Data Types) 。 Shape での例が挙げられている。

data Point = Point
  { x :: Number
  , y :: Number
  }

data Shape
  = Circle Point Number
  | Rectangle Point Number Number
  | Line Point Point
  | Text Point String

IntString だけでなく ArrayRecord や ADT も含むことができる。型構築子 (type constructor) とデータ構築子 (data constructor) の違いを理解すべき。なるほど。

data 型構築子 = データ構築子 [| データ構築子 [| ...]] という形式で定義するようだ。

また Language Guide では Tagged Unions として書かれている。ふむ。

Language Guide:

Tagged Unions - Language Guide

他の例として MaybeList が挙げられている。それぞれ purescript-maybe パッケージと purescript-lists パッケージから来ている。

data Maybe a = Nothing | Just a
data List a = Nil | Cons a (List a)

Maybe は値がない (Nothing) 、または (|) ただの a (Just a) を表している。Nothing / Just というデータ構築子がある。 a は任意の型だろう。

List は空のリスト (Nil) 、または (|) 要素 a と残りのリスト (List a) から構成 (Cons) されることを表している。再帰的だ。 Nil / Cons というデータ構築子がある。 a は任意の型だろう。

PureScript by Example 5.13

使ってみる。

exampleLine :: Shape
exampleLine = Line p1 p2
  where
    p1 :: Point
    p1 = Point { x: 0.0, y: 0.0 }

    p2 :: Point
    p2 = Point { x: 100.0, y: 50.0 }

Line を使って Shape を構築している。 Line のために Point をふたつ構築している。特に難しいことはない。

次の例。

showPoint :: Point -> String
showPoint (Point { x, y }) =
  "(" <> show x <> ", " <> show y <> ")"

showShape :: Shape -> String
showShape (Circle c r) =
  "Circle [center: " <> showPoint c <> ", radius: " <> show r <> "]"
showShape (Rectangle c w h) =
  "Rectangle [center: " <> showPoint c <> ", width: " <> show w <> ", height: " <> show h <> "]"
showShape (Line start end) =
  "Line [start: " <> showPoint start <> ", end: " <> showPoint end <> "]"
showShape (Text loc text) =
  "Text [location: " <> showPoint loc <> ", text: " <> show text <> "]"

今度はパターンマッチでデータ構築子を使っている。代数的データ型で列挙しているものが網羅されているかの検査もされる。良い。代数的データ型とパターンマッチがうまく組み合わされていると感じる。

PureScript by Example 5.14

showPoint を再掲する。 Record の中身がうまく取り出せているのが分かる。 JavaScript は ES2015 以降で似たような文法が有効になっているので、そこまで違和感はないはずだ。

showPoint :: Point -> String
showPoint (Point { x, y }) =
  "(" <> show x <> ", " <> show y <> ")"

取り出せるように、組み立てることもできる。

origin :: Point
origin = Point { x, y }
  where
    x = 0.0
    y = 0.0

ふむ。

まとめ

代数的データ型の箇所を扱った。明日は newtype か。

参考

次回以降の TODO

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
2