2012-01-11 2 views
6

Можно сделать следующее:Возможна ли постановка в виде области действия?

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

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

мне нужно только использовать этот пользовательский тип внутри, где положение, так что не имеет смысла определять его глобально.

+0

Я полагаю, это предполагает, что 'meh' не является полиморфным? –

ответ

8

Это невозможно. Почему бы просто не определить его над функцией? Вам не нужно экспортировать его из модуля (просто используйте явный список экспорта).

Кстати, если у вас действительно есть такой большой тип, это, вероятно, признак того, что вы должны учитывать его на более мелкие части, особенно если у вас много кортежей, как показывает ваш пример; типы данных будут более уместными.

8

На самом деле, есть один, немного смешно, способ приблизить это:

{-# 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 = {- ... -} 

Я не могу рекомендовать позволяя два расширения языка только ради сокращающих типов в подписи, хотя, если вы уже используя их (или GADT вместо семейств типов), я полагаю, что это ничем не повредит.

Чувствительность в стороне, вы должны рассмотреть возможность реорганизации своих типов в таких случаях, как это предлагает ehird.

+1

Очень мило! Нужны ли переменные типа области видимости? (Похоже, что равенство типа - это действительно умный бит, и это может быть перенесено в тип 'meh'.) –

+0

Вы забыли' RankNTypes'. – ehird

+0

@ DanielWagner: Для сокращения аббревиатуры требуется только ограничение равенства, да. Но вопрос конкретно касался типа * scoped *, поэтому его не распространялось на предложение 'where', которое было бы неудовлетворительным. :] –

Смежные вопросы