LoginSignup
0
2

More than 5 years have passed since last update.

PureScript by Example の 5.10, 5.11 を読む

Last updated at Posted at 2016-12-15

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

概要

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

今日は 5.10 から読んでいく。

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

前回のおさらい

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

Number String Char Boolean Array Record のパターンマッチを見た。またガードを書けること、ネストできること、@ で名前をつけられることも見た。

Language Guide:

PureScript by Example 5.10

case 式。パターンマッチは Top-level declaration 以外でもできるらしい。そのための構文が case だ。

import Data.Array.Partial (tail)
import Data.Foldable (sum)
import Partial.Unsafe (unsafePartial)

lzs :: Array Int -> Array Int
lzs [] = []
lzs xs = case sum xs of
           0 -> xs
           _ -> lzs (unsafePartial tail xs)

この場合も _ のパターンを除くと、コンパイルエラーになる。

PureScript by Example 5.11

パターンマッチの失敗と部分関数。いままでなんとなく書かれてきた unsafePartial のこと。

パターンマッチですべてのパターンが網羅されていない場合、通常 PureScript だとコンパイルエラーになるはずだ。強引に定義しようとすると unsafePartial を使えば良い。


import Partial.Unsafe (unsafePartial)

partialFunction :: Boolean -> Boolean
partialFunction = unsafePartial \true -> true

false の場合のパターンを網羅できていないが、コンパイルエラーにはならない。ただし実行すると次のようにエラーとなる。

> import Main
> partialFunction false
/Users/bouzuya/.ghq/github.com/paf31/purescript-book/exercises/chapter5/.psci_modules/node_modules/Main/index.js:14
            throw new Error("Failed pattern match at Main line 29, column 19 - line 29, column 42: " + [ v.constructor.name ]);
            ^

Error: Failed pattern match at Main line 29, column 19 - line 29, column 42: Boolean
    at /Users/bouzuya/.ghq/github.com/paf31/purescript-book/exercises/chapter5/.psci_modules/node_modules/Main/index.js:14:19
    at Object.partialFunction (/Users/bouzuya/.ghq/github.com/paf31/purescript-book/exercises/chapter5/.psci_modules/node_modules/Main/index.js:15:11)
    at Object.<anonymous> (/Users/bouzuya/.ghq/github.com/paf31/purescript-book/exercises/chapter5/.psci_modules/node_modules/$PSCI/index.js:6:15)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.require (module.js:497:17)
    at require (internal/module.js:20:19)

どんな入力に対しても値を返せる関数を全域関数 (total function) 、そうでないものを部分関数 (partial function) と呼ぶらしい。

PureScript では下記のように重複している場合に警告される。

redundantCase :: Boolean -> Boolean
redundantCase true = true
redundantCase false = false
redundantCase false = false

上記はエラーにはされないが、警告はされる。

Pursuit:

実装を見ると……。

-- | Discharge a partiality constraint, unsafely.
foreign import unsafePartial :: forall a. (Partial => a) -> a

exports.unsafePartial = function (f) {
  return f();
};

Partial => a なものを a にするだけみたい。

=> の話はまたそのうち出てくるはず。おそらく 6 章だろう。

まとめ

代数的データ型に入ろうかと思ったのだけど、中途半端なので明日へ送る。

参考

次回以降の TODO

0
2
0

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
0
2