2012-01-11 4 views
6

は、次の操作を実行することが可能です:スコープ付きのタイプステートメントが可能ですか?

foo = bar 
    where 
     type A = (Some, Huge, Type, Sig) 

     meh :: A -> (A, A) -> A 

私はそれがグローバルに定義しても意味がありませんので、where句内でこのカスタムタイプを使用する必要があります。

+0

これは 'meh'が多型ではないと仮定していると思いますか? –

答えて

8

これはできません。なぜ関数の上に定義するだけではないのですか?モジュールからエクスポートする必要はありません(明示的なエクスポートリストを使用するだけです)。

ところで、あなたが本当に大きな型を持っているのなら、それはおそらく、あなたの例として示唆しているようにタプルがたくさんある場合は、それを小さな部分に分解しなければならないという兆候でしょう。データ型がより適切になります。

8

は実は、これを近似する1、少しばかげて、方法があります:

{-# LANGUAGE TypeFamilies #-} 
{-# LANGUAGE ScopedTypeVariables #-} 

foo :: forall abbrv. (abbrv ~ (Some, Huge, Type, Sig)) 
    => abbrv -> abbrv 
foo x = meh x (x, x) 
    where meh :: abbrv -> (abbrv, abbrv) -> abbrv 
     meh x y = {- ... -} 

あなたは既にしている場合けれども、私は本当に、ただの署名に種類の省略のために2言語拡張を有効にすることをお勧めすることはできませんそれらを使用して(またはタイプファミリーの代わりにGADT)私はそれが本当に何かを傷つけることはないと思います。

賢明に別に、あなたはこのような場合には、あなたのタイプをリファクタリングすることをお勧めします。

+1

非常にかわいい!スコープ付きの型変数は本当に必要ですか? (型の平等は本当に巧妙なビットであり、それは 'meh'の型に移動することができます) –

+0

' RankNTypes'を忘れました。 – ehird

+0

@DanielWagner:略語trickには等価制約のみが必要です。しかし、問題は具体的には*スコープ型であるため、 'where'節にそれを拡張しないと、不満を抱いていました。 :] –

関連する問題