LoginSignup
1
0

More than 3 years have passed since last update.

Pythonで、配列要素のデータ型と、配列の長さを型検査する依存型ライクなメソッドを作ってみた

Posted at

定義したメソッド

自作クラスを宣言するときに、定義するクラスが用いるデータ型に制約を与えるのと同時に、そのクラスのインスタンスが持ちうる値の範囲や、長さの範囲にまで、制約を与えることができる言語は、依存型や篩型の型クラスを宣言できる言語として、知られています。

Idrisやv6.11以降のRacket言語が、これらの型を宣言し、静的な型検査を行うことができる言語です。

Dependent Types と Refinement Types の違い
Refinement Types For Haskell
型をさらに拡張するーーRefinement Typesについて
LiquidHaskell のインストールと学習方法
Liquid Haskell で普通の型システムの上を行け #NGK2017B

これらの言語は、関数型言語です。Haskellが、関数型言語として、Qiitaでも多くの良質な記事が書かれています。

元々は手続き型言語であったPythonでも、以下のように、関数型言語のスタイルを取り入れる動きが進行中です。

  1. 型アノテーションの導入(typingモジュール)
  2. 外部のツールとして、静的な型検査を行うmypyの登場
  3. mapreduceの多様
  4. 破壊的代入が可能なListではなく、破壊的代入が言語レベルの仕様で禁止されているtuple型の利用を推奨するプログラミングスタイルの普及

こうした流れを受けて、この記事では、Pythonで「依存型」クラスを実現するための一歩として、ある配列オブジェクトの要素が持つデータ型と、配列全体の長さを検査するメソッドを定義してみました。

定義したメソッドの返り値は、bool型(TrueもしくはFalseのいずれか)です。

定義するメソッドが行う型検査の内容


  1. 第1引数に渡した配列の要素がすべてstr型のオブジェクトであるかどうか。
  2. 配列の要素数が第2引数に渡した数値未満であるかどうか。

以下、Ipythonの対話型インタプリタで実行しました。

Python3
In [1]: from typing import List, Sequence, TypeVar

In [2]: T = TypeVar('T')

In [3]: def func_(x: List[T], n: int) -> bool:
    ...:     condition_1 = (len(x)  < n)
    ...:     condition_2 = not(False in [isinstance(elem, str) for elem in x])
    ...:     condition = (condition_1 and condition_2)
    ...:     return condition
    ...: 

( 動作確認 )

以下の2つの条件が揃った場合のみ、Trueが帰ることが確認できました。

( AND条件 )
1. 第1引数に渡した配列の要素がすべてstr型のオブジェクトである。
2. 配列の要素数が第2引数に渡した数値未満である。

Python3
In [4]: test_list = [1, 2, 3, "a", 1, 5, 9, 10, 17]

In [5]: result = func_(test_list, 7)

In [6]: print(result)
False


In [7]: test_lis2t = [1, 2, 3, "a", 1]

In [8]: test_list2 = [1, 2, 3, "a", 1]

In [9]: result = func_(test_list2, 7)

In [10]: print(result)
False

In [11]: test_list = [1, 2, 3, 1, 5, 9, 10, 17]

In [12]: result = func_(test_list, 7)

In [13]: print(result)
False

In [14]: test_list2 = [1, 2, 3]

In [15]: result = func_(test_list2, 7)

In [16]: print(result)
False

In [17]: test_list3 = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]

In [18]: result3 = func_(test_list3, 7)

In [19]: print(result3)
False

In [20]: test_list4 = ["a", "b", "c"]

In [21]: result4 = func_(test_list4, 7)

In [22]: print(result4)
True

In [23]: test_list5 = ["a", "b", 1, 3]

In [24]: result5 = func_(test_list5, 7)

In [25]: print(result5)
False

In [26]: 
1
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
1
0