LoginSignup
3
0

More than 5 years have passed since last update.

Freer Effectsが、だいたいわかった: 11-2 TypeOperators拡張

Last updated at Posted at 2017-10-17

Freer Effectsが、だいたいわかった: 11-2 TypeOperators拡張

目次

(0). 導入

  1. Freeモナドの概要
    • Freeモナドとは
    • FreeモナドでReaderモナド、Writerモナドを構成する
  2. 存在型(ExistentialQuantification拡張)の解説
  3. 型シノニム族(TypeFamilies拡張)の解説
  4. データ族(TypeFamilies拡張)の解説
  5. 一般化代数データ型(GADTs拡張)の解説
  6. ランクN多相(RankNTypes拡張)の解説
  7. FreeモナドとCoyoneda
    • Coyonedaを使ってみる
    • FreeモナドとCoyonedaを組み合わせる
      • いろいろなモナドを構成する
  8. Freerモナド(Operationalモナド)でいろいろなモナドを構成する
    • FreeモナドとCoyonedaをまとめて、Freerモナドとする
    • Readerモナド
    • Writerモナド
    • 状態モナド
    • エラーモナド
  9. モナドを混ぜ合わせる(閉じた型で)
    • Freerモナドで、状態モナドとエラーモナドを混ぜ合わせる
      • 両方のモナドを一度に処理する
      • それぞれのモナドを、それぞれに処理する
  10. 存在型による拡張可能なデータ構造(Open Union)
  11. 追加の言語拡張
    1. ScopedTypeVariables拡張
    2. TypeOperators拡張
    3. KindSignatures拡張
    4. DataKinds拡張
    5. MultiParamTypeClasses拡張
    6. FlexibleInstances拡張
    7. OVERLAPSプラグマ
  12. Open Unionを型によって安全にする
  13. モナドを混ぜ合わせる(開いた型で)
    • FreeモナドとOpen Unionを組み合わせる
    • 状態モナドにエラーモナドを追加する
  14. Freer Effectsで、IOモナドなどの、既存のモナドを使用する
  15. 関数を保管しておくデータ構造による効率化
  16. いろいろなEffect
    • 関数handleRelayなどを作成する
    • NonDetについて、など

直積と直和

Haskellでは型を組み合わせることができる。組み合わせかたには「ふたつの型の両方の値をもつ型をつくる」、または、「ふたつの型の、どちらかの値をもつ型をつくる」というやりかたがある。それぞれ、「直積」「直和」のようによぶ。

直積

ふたつの型の両方の値をもつ値は、つぎのように表現できる。

> ('c', True)
('c',True)
> :type it
it :: (Char, Bool)

代数的データ型では、つぎのようになる。

> data Product a b = Product a b deriving Show
> Product 'c' True
Product 'c' True
> :type it
it :: Product Char Bool

これを直積とよぶ。値の「数」を考えると「積」であることが直観的によくわかる。TrueとFalseとの、ふたつの値をもつBool型と、A、B、Cという、みっつの値をもつT型との直積型は、つぎのようになる。

(Bool, T)

この型に属する値は、つぎのようになる。

(False, A)
(False, B)
(False, C)
(True, A)
(True, B)
(True, C)

このように2個の値をもつ型と、3個の値をもつ型との直積である型は、6個の値をもつ。「2かける3で6」だ。

直和

ふたつの型の、どちらかの型の値をもつ型の値は、つぎのように表現できる。

> Left 'c' :: Either Char Bool
Left 'c'
> :type it
Either Char Bool

代数的データ型では、つぎのようになる。

> data Sum a b = L a | R b deriving Show
> L 'c' :: Sum Char Bool
L 'c'
> :type it
it :: Sum Char Bool

これを直和とよぶ。値の「数」を考えてみよう。TrueとFalseの、ふたつの値をもつBool型と、A、B、Cという、みっつの値をもつT型との直和型は、つぎのようになる。

Either Bool T

この型に属する値は、つぎのようになる。

Left False
Left True
Right A
Right B
Right C

このように2個の値をもつ型と、3個の値をもつ型との直和である型は、5個の値をもつ。「2たす3で5」だ。

直積型と直和型を定義する

タプルとEither型は、そのまま直積と直和である。また、代数的データ型も、そのままで直積と直和を表現できる。なので、ここで新たな「直積型」「直和型」を定義する理由はないが、説明の都合上、定義することとする。ファイルproductSum.hsを作成する。

productSum.hs
data Product a b = Product a b deriving Show
data Sum a b = L a | R b deriving Show

x :: Sum (Product Char Bool) (Product String Integer)
x = L $ Product 'c' True

試してみる。

> :load productSum.hs
> x
L (Product 'c' True)
> :type x
x :: Sum (Product Char Bool) (Product String Integer)

値構築演算子

値構築演算子を使うと、直積型はより読みやすくなる。productSum.hsの、データ型Productの定義を修正する。

productSum.hs
data Product a b = a :*: b deriving Show

値構築演算子は、ふつうの演算子と名前空間がおなじなので、区別するために、その名前には:(コロン)から、はじまる識別子を使う。最後にも:(コロン)をつけたのは、そのほうが見た目のバランスがいいからで、とくに深い意味はない。サンプルの値xの定義も修正する。

productSum.hs
x = L $ 'c' :*: True
> :reload
> x
L ('c' :*: True)
> :type x
x :: Sum (Product Char Bool) (Product String Integer)

型構築演算子

さて、関数にたいして演算子があり、値構築子にたいして値構築演算子がある。それでは、型構築子にたいして型構築演算子は使えるだろうか。使える。そう、GHCならね。つぎのようにファイルproductSumTypeOp.hsを作成する。

productSumTypeOp.hs
{-# LANGUAGE TypeOperators #-}

data a * b = a :*: b deriving Show
data a + b = L a | R b deriving Show

x :: (Char * Bool) + (String * Integer)
x = L $ 'c' :*: True

演算子と型構築演算子とは、名前空間が異なるので、おなじ名前を使うことができる。対話環境で試してみよう。

> :load productSumTypeOp.hs
> x
L ('c' :*: True)
> :type x
x :: (Char * Bool) + (String * Integer)

型構築演算子の結合力

型構築演算子の結合力を変えることもできる。つぎのように結合力の宣言を追加する。

productSumTypeOp.hs
infixl 7 *
infixl 6 +

サンプルの値xの型宣言を書き直す。

productSumTypeOp.hs
x :: Char * Bool + String * Integer

ただし、演算子と型構築演算子の結合力をばらばらに設定することは、たぶん、できない。対話環境で試しておこう。

まとめ

関数にたいして演算子が、値構築子にたいして値構築演算子がある。GHCでは言語拡張TypeOperatorsを有効にすることで、型構築子にたいして型構築演算子を使うことができる。

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