2012-01-11 12 views
6

Czy to możliwe, aby wykonać następujące czynności:Czy możliwe jest określenie zakresu informacji?

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

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

Muszę tylko do korzystania z tego typu niestandardowego wewnątrz gdzie klauzuli, więc nie ma sensu, aby zdefiniować ją globalnie.

+0

Przypuszczam, że to przy założeniu, że 'meh' nie jest polimorficzny? –

Odpowiedz

8

To nie jest możliwe. Dlaczego nie zdefiniować go powyżej funkcji? Nie musisz eksportować go z modułu (wystarczy użyć jawnej listy eksportu).

Nawiasem mówiąc, jeśli naprawdę masz typ, który jest duży, prawdopodobnie jest to znak, że powinieneś złożyć go na mniejsze części, szczególnie jeśli masz dużo krotek, jak sugeruje twój przykład; typy danych byłyby bardziej odpowiednie.

8

Właściwie jest jedna, nieco śmieszny, to sposób na zbliżenie:

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

Nie mogę polecić umożliwiając dwa rozszerzenia języka właśnie ze względu na skrócenie rodzajów podpisów, choć jeśli jesteś już używając ich (lub GADT zamiast rodzin typów) Przypuszczam, że tak naprawdę nic nie boli.

Na marginesie, powinieneś rozważyć refaktoryzację swoich typów w takich przypadkach, jak sugeruje ehird.

+1

Bardzo urocze! Czy zmienne typu zakresowego są naprawdę potrzebne? (Wygląda na to, że równość jest naprawdę sprytnym bitem i można ją przenieść do typu 'meh'.) –

+0

Zapomniałeś o' RankNTypes'. – ehird

+0

@DanielWagner: Tylko ograniczenie równości jest wymagane w przypadku sztuczki skrótowej, tak. Ale pytanie dotyczyło raczej typu * scoped *, więc nie przedłużenie go do klauzuli "where" byłoby niezadowalające. :] –

Powiązane problemy