8

部分的に適用される型のデータコンストラクタをHaskellで作成できますか?部分的に適用された型のデータコンストラクタをHaskellで作成する

のGHCiセッション:

Prelude> data Vector a b = Vector {x::a, y::b} 
Prelude> :t Vector 
Vector :: a -> b -> Vector a b 
Prelude> type T1 = Vector Int 
Prelude> :t T1 
<interactive>:1:1: Not in scope: data constructor `T1' 
Prelude> let x = Vector 
Prelude> let y = T1 
<interactive>:46:9: Not in scope: data constructor `T1' 

私はタイプT1のデータコンストラクタを作成したい - それも可能ですか?あるいは、このような関数を手動で定義することはできないので、newtypeを使用する必要がありますか?

+0

[このページ](https://webcache.googleusercontent.com/search?q=cache:3GDV7F446NMJ:www.haskell.org/pipermail/haskell-cafe/2013-May/108350.html+&cd= 1&hl = en&ct = clnk&gl = us)が役に立つかもしれません。 –

+1

タイプ 'T1'には値が含まれていないので、そのための'コンストラクタ 'を作成することはできません。 – augustss

+1

FYIでは、 "型の型"はghciで ':kind T1'を実行することで得ることができる* kind *と呼ばれます。 – Wes

答えて

4

GADTでこれを行うことができます。 GHCiのセッション:

λ :set -XGADTs 
λ :{ 
| data Vector a b where 
|  Vector :: a -> b -> Vector a b 
|  T1 :: Int -> b -> T1 b 
| type T1 = Vector Int 
| :} 
λ :t T1 
T1 :: Int -> b -> T1 b 
6

私はあなたの目標が何であるかについての少し混乱している、しかし、のはビットで、このビットを通過し、多分私は右のポイントを打つだろうしましょう:

:tはあなた伝えます変数のタイプ;あなたが渡したものを正確に返すだけなので、型に適用すると意味がありません。ここでエラーが:tがパラメータとしてデータ値のいくつかの種類を期待していることを教えて注意してください:

Prelude> :t Maybe 

<interactive>:1:1: Not in scope: data constructor `Maybe' 
Prelude> :t (Maybe Integer) 

<interactive>:1:2: Not in scope: data constructor `Maybe' 

<interactive>:1:8: Not in scope: data constructor `Integer' 

あなた部分のタイプを作成することができます

Prelude> type T = Maybe 
Prelude> Just 5 :: T Integer 
Just 5 

type T a = Maybe a -- alternately, with explicit type parameters 
Prelude> Just 'a' :: T Char 
Just 'a' 

あなたはを作成することはできませんがパーシャルタイプのデータコンストラクタは、データを表さないためです。タイプにパラメータ化されていないMaybeまたはVectorの値はどのような値ですか?あなたはMaybeNothingを持つことができることを考えるように傾斜するかもしれないが、Nothingは次のように入力されている:

Prelude> :t Nothing 
Nothing :: Maybe a 

Nothing任意のMaybe aことができるということでキーを、それはまだそれがNothingだ知っているaを必要とします。 (私に何かのガラスを取ってもらうのではなく、あなたが「私に一杯飲んだ」と言ったら、少なくとも私の思考が終わるまで、あなたは正当に遵守できません。

あなたは確かに部分的にそれらが適用されていたら、完全タイプを返します機能適用作成することができます。

Prelude> let f = Just :: a -> T a 
Prelude> f 5 
Just 5 
Prelude> :t f 'a' 
f 'a' :: T Char
1

T1のコンストラクタはすでにあり、それはVector命名されています。

*Main> :t Vector :: Int -> b -> T1 b 
Vector :: Int -> b -> T1 b :: Int -> b -> T1 b 
1
Prelude> type T1 = Vector Int 

Vector Intの場合はタイプのコンストラクタが作成されます。ここでVectorタイプのコンストラクタとして使用されることに注意してください。タイプ引数を指定するからです。あなたはタイプ:kT1種類を照会することができます

Prelude> :k T1 
T1 :: * -> * 

これはT1は、具体的なタイプ(*)を取り、具体的なタイプを返すタイプのコンストラクタであることを示しています。 データコンストラクタを作成するには

、あなたはVectorデータコンストラクタの最初のパラメータにデータ価値を提供する必要があります。

Prelude> let t1 = Vector 5 
Prelude> :t t1 
t1 :: b -> Vector Integer b 

Vectorは* タイプの両方であることに注意してくださいコンストラクタとデータコンストラクタは、data宣言の左右に同じ名前を使用しているためです)

関連する問題