PureScript by Example の 5.15 を読む

この記事は [(bouzuya) PureScript Advent Calendar 2016](http://www.adventar.org/calendars/1494) の 17 日目。 (bouzuya) PureScript Advent Calendar 2016 は bouzuya の PureScript 学習の記録だ。

- ← 16 日目『 [PureScript by Example の 5.12, 5.13, 5.14 を読む - Qiita][2016-12-16] 』
- → 18 日目『 [PureScript by Example の 5.16, 5.17, 5.18 を読む - Qiita][2016-12-18] 』

## 概要

[PureScript by Example][purescript-by-example] を [PureScript Language Guide][language-guide] や [Pursuit][pursuit] を見ながら進めていく。

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

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

- [PureScript by Example][purescript-by-example] 2016-12-05 時点で 0.10.x 向け
- [実例による PureScript][purescript-by-example-ja] 2016-12-05 時点で 0.7 向け
- [PureScript Language Guide][language-guide] 対象バージョン不明

## 前回までのおさらい

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

`Number` `String` `Char` `Boolean` `Array` `Record` のパターンマッチを見た。またガード・パターンマッチのネスト・ `@` で名前付け・ `case` 式・部分関数と `unsafePartial` を見た。`data` で定義できる代数的データ型とそれを使ったパターンマッチを見た。

Language Guide:

- [Top-level declarations][language-guide-top-level-declarations]

## PureScript by Example 5.15

`newtype` 。代数的データ型のうち、ひとつの構築子とひとつの引数だけを取るもののときに使える。つまり既存の型に新しい名前をつけるもの。実行時には同じものとして扱われるが、型システム上は別のものとして扱われる。

Language Guide:

- [Newtypes - Language Guide][language-guide-newtypes]

```
newtype Pixels = Pixels Number
newtype Inches = Inches Number
```

なるほど。間違えて `Inches` に `Pixels` を指定しなくて済む。実行時には同じものなので、性能上のデメリットがない、と。

ためしてみる。

```
f :: Inches -> Number
f (Inches n) = n
```

```
> f (Inches 10.0)
10.0

> f (Pixels 10.0)
Error found:
in module $PSCI
at  line 1, column 4 - line 1, column 15

  Could not match type

    Pixels

  with type

    Inches


while checking that type Pixels
  is at least as general as type Inches
while checking that expression Pixels 10.0
  has type Inches
in value declaration it

See https://github.com/purescript/purescript/wiki/Error-Code-TypesDoNotUnify for more information,
or to contribute content related to this error.
```

当然、エラーになる。

`pulp browserify` した結果を見てみる。確かに違いがない。

```
// ...
// Generated by psc version 0.10.2
"use strict";
var Pixels = function (x) {
    return x;
};
var Inches = function (x) {
    return x;
};
var f = function (v) {
    return v;
};
module.exports = {
    Inches: Inches,
    Pixels: Pixels,
    f: f
};
// ...
```

## まとめ

`newtype` だけ。進んでいない。

## 参考

- [PureScript by Example][purescript-by-example]
- [実例による PureScript][purescript-by-example-ja]
- [paf31/purescript-book][paf31/purescript-book]
- [Language Guide][language-guide]
- [Language Guide - Newtypes][language-guide-newtypes]

## 次回以降の TODO

- PureScript by Example & PureScript Language Guide を読み進める
- `Array` 以外での `do` 記法
- Newtype
- `psc-package`
- [24 Days of PureScript, 2016][paf31/24-days-of-purescript-2016]
- [24 Days of PureScript, 2014](https://gist.github.com/paf31/8e9177b20ee920480fbc)
- 某氏の記事の紹介
- [github.com/purescript](https://github.com/purescript/) のコードを読む
- [github.com/purescript-node](https://github.com/purescript-node) のコードを読む
- [github.com/purescript-contrib](https://github.com/purescript-contrib) のコードを読む

[paf31/24-days-of-purescript-2016]: https://github.com/paf31/24-days-of-purescript-2016
[2016-12-01]: http://qiita.com/bouzuya/items/a5be85ec3e496e5bf436
[2016-12-02]: http://qiita.com/bouzuya/items/806335ea74ead0e33d95
[2016-12-03]: http://qiita.com/bouzuya/items/86cc9aaaddcc1aa790cf
[2016-12-04]: http://qiita.com/bouzuya/items/b2b80c22c50d0c1e739c
[2016-12-05]: http://qiita.com/bouzuya/items/f19ee0b86e9aec3f0afa
[2016-12-06]: http://qiita.com/bouzuya/items/4694ac25f68931115319
[2016-12-07]: http://qiita.com/bouzuya/items/62c6ad30ecba3c68a7a3
[2016-12-08]: http://qiita.com/bouzuya/items/7224535dd053c41748ed
[2016-12-09]: http://qiita.com/bouzuya/items/868eafc19b96619c025a
[2016-12-10]: http://qiita.com/bouzuya/items/1a54ba3702f9818527a5
[2016-12-11]: http://qiita.com/bouzuya/items/ab2bc2d19461203f1ee5
[2016-12-12]: http://qiita.com/bouzuya/items/c42ddb14477716de1dcf
[2016-12-13]: http://qiita.com/bouzuya/items/a49463871a96459d7083
[2016-12-15]: http://qiita.com/bouzuya/items/0511f040381c6c2eba12
[2016-12-16]: http://qiita.com/bouzuya/items/10d8f935c0e5695826c5
[2016-12-18]: http://qiita.com/bouzuya/items/ae7ce46363d0ccdfb03b
[purescript-by-example]: https://leanpub.com/purescript/read
[purescript/purescript]: https://github.com/purescript/purescript
[pursuit]: https://pursuit.purescript.org/
[purescript/documentation]: https://github.com/purescript/documentation
[purescript-by-example-4]: https://leanpub.com/purescript/read#leanpub-auto-recursion-maps-and-folds
[purescript-by-example-5]: https://leanpub.com/purescript/read#leanpub-auto-pattern-matching
[purescript-by-example-ja]: http://hiruberuto.bitbucket.org/purescript/
[try-purescript]: http://try.purescript.org/
[language-guide]: https://github.com/purescript/documentation/tree/f48ba1ee7761446e1ae75ee806e51688c1937297/language/

[language-guide-newtypes]: https://github.com/purescript/documentation/blob/f48ba1ee7761446e1ae75ee806e51688c1937297/language/Types.md#newtypes
[paf31/purescript-book]: https://github.com/paf31/purescript-book/tree/8ad7d2af75ad4c795d5075018e9ee45005799e6f/
[purescript-book-chapter-5]: https://github.com/paf31/purescript-book/tree/8ad7d2af75ad4c795d5075018e9ee45005799e6f/exercises/chapter5
[language-guide-top-level-declarations]: https://github.com/purescript/documentation/blob/f48ba1ee7761446e1ae75ee806e51688c1937297/language/Syntax.md#top-level-declarations