2017-03-17 17 views
0

今日、変数型について述べました。しかし、私はそれが何を意味するのか理解していません。haskell/Javaの型変数とは何か

私は説明を数学で理解していますが、プログラミングについてはまだ分かりません。誰か説明をすることはできますか?

+0

が、それらは数学的な意味ででは実装されていません。 Java。そして、私がhaskellを聞いたとき、私は[monad](https://wiki.haskell.org/Monad)と思う(しかし、私は実際にはhaskellを知らない)。 –

+0

*型変数はどこに記述されましたか?とにかく、Javaジェネリック型変数(「[型パラメータ](https://docs.oracle.com/javase/tutorial/java/generics/types.html)」とも呼ばれています) Java™チュートリアル」)? – Andreas

+1

@Andreasまあ、ちょうど今あなたのために... –

答えて

0

タイプ変数では、指定されていないタイプのもの(数値、テキストなど)のデータ型/コンテナを定義できます。簡単な例を提供するために、あなたが望むものを置くことができるボックスが欲しいと想像してください。ここ

(Tは型変数である)は、Javaの例である:ここ

public class Box<T> { 
    private T thing; 

    public void putThing(T thing) { 
     this.thing = thing; 
    } 
} 

は、(aは型変数)Haskellの例である:

data Box a = PutThing a 

もう一つの良いです例は汎用タプルデータ型です。


例は、両方の場合において、型変数は、現在指定されたタイプであり、

注ユースケース。

のJava:(GHCiの中)

Box<String> box = new Box<String>(); 
box.putThing("42");  

ハスケル:私はあなただけの型変数のためのOCamlの例を見つけるつもりだと思います

:t (PutThing (42::Int)) 
(PutThing (42::Int)) :: Box Int 
1

タイプ変数は、複数の異なるタイプの値に作用する単一の関数/メソッドを記述することによって多形性を持つ方法です。ここでHaskellの例である:

id :: forall a. a -> a 
id x = x 

型シグネチャにおけるa型変数であり、そしてforallが示すように、この機能は、異なる種類の「すべてに」作用します。たとえば、Int -> Intのように、またはChar -> Charのようにidを使用できます。

id (5 :: Int) = 5 :: Int 
id 'a' = 'a' 

idは、このようなid :: Int -> Intとして(その中の型変数なしの意味)の具体的な種類を与えた場合'a'のタイプ(Char)がIntと一致しないため、その後、id 'a'は型エラーになります。

通常、型変数の使用から容易に推論できるので、forallid :: a -> a)は省略しますが、実際に何が起こっているのかを理解するのに役立ちます。

私はHaskellほどJavaは分かりませんが、Genericsは型変数を使用する方法だと思われますので、ArrayList<A>は非プリミティブ型Aで動作する配列リストを意味します。

+0

Java汎用型はプリミティブ型では機能せず、コンパイル時の安全システムです(コンパイル時にほとんど*消去されます)。だから、彼らはどんな意味でも「純粋」ではありません... –

+0

@ElliottFrisch彼らはプリミティブ型では動作しないとはどういう意味ですか? 'ArrayList 'を使用できませんか? [Haskellのすべての*型情報は実行時に消去されます](http://stackoverflow.com/questions/12468722/does-haskell-erase-types)、それらはその点で似ています。これがどのように「純粋」なのか、どのように影響しますか? 「副作用なし」のように純粋な意味があるのなら、それがどういう意味で当てはまるのか分かりません。 – Lazersmoke

+0

いいえ、あなたは 'ArrayList ' *または* 'ArrayList 'を使用することはできません。ラッパーの種類を使用する必要があります。 –

2

これは非常に簡単です。基本的な考え方は、IntやBool、Charのような基本型だけでなく、他の型からなる型もあります。

最も簡単な例はリストです。型安全な言語では、リストのすべての要素は同じ型でなければなりません。それで、私たちは次のように書いています:

Haskell Java    Explanation 
[Int]  List<Integer>  list of integers 
[Char] List<Character> list of characters 

など。これは既にうまくいっていますが、十分にいいわけではありません。リスト上の特定の関数は、要素の型を除いて完全に同一であり、要素の型は関数内では無関係であることが分かります。次に例を示します。

lengthIntList :: [Int] -> Int -- compute length of a list of int 
lengthIntList [] = 0 
lengthIntList (x:xs) = 1 + length xs 

lengthCharList :: [Char] -> Int -- compute length of a list of char 
lengthCharList [] = 0 
lengthCharList (x:xs) = 1 + length xs 

は、したがって、次のステップは、要素型から抽象化していると言う:これは、すべてのタイプの場合:

length :: [a] -> Int  -- length of a list, for all elemen types 
length [] = 0 
length (x:xs) = 1 + length xs 

ここで、aは言う型変数であります関数lengthはそのタイプのリストを取り、Intを返します。

2

ウィキペディアからの例はaのタイプはタイプパラメータTに結合され、この

public static <T> T identity(T a) { 
    return a; 
} 

ようなJavaで記述することができます。したがって、IntegerのID関数を呼び出すとIntegerが返され、Stringと呼び出すとStringに戻ります。

非常に一般的な使用例は、文字列のリストのような同じタイプの値のコレクションであろう:Listインタフェースで

List<String> as = new ArrayList<String>(); 

タイプパラメータは、そのリストの必須のStringしたがって、すべての要素に結合されていますタイプはStringです。

更新されたコードスニペット、感謝のエリオット。

+0

あなたの例では 't'とは何ですか?あなたは 'return a;'を意味しましたか? –

関連する問題