8

Czy jest możliwe utworzenie konstruktora danych dla częściowo zastosowanego typu w Haskell?Utwórz konstruktor danych dla częściowo zastosowanego typu w Haskell

ghci sesja:

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' 

Chcę utworzyć konstruktor danych dla typu T1 - czy to w ogóle możliwe? Czy muszę używać nowych typów, ponieważ nie jest możliwe ręczne zdefiniowanie takiej funkcji?

+0

Myślę [tę stronę] (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) mogą być przydatne. –

+1

Typ 'T1' nie zawiera żadnych wartości, więc nie można utworzyć dla niego" konstruktora ". – augustss

+1

FYI, "typ typu" nazywany jest * rodzajem *, który można uzyskać wykonując ': rodzaj T1' w ghci. – Wes

Odpowiedz

4

GADT mogą to zrobić. GHCi sesja:

λ :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

jestem trochę mylić, co twoim celem jest, ale chodźmy przez ten krok po kroku, a może będę klikniemy prawym punkt:

:t Informuje typ zmiennej ; nie ma sensu, gdy jest zastosowany do typu, ponieważ po prostu zwróci dokładnie to, co przekazałeś. Wskazówki Tutaj błędy wam powiedzieć, że :t oczekuje jakieś wartości danych jako parametr:

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' 

Ty może utworzyć typ częściowej:

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' 

Ty nie utworzyć konstruktor danych dla częściowego typu, ponieważ nie reprezentują danych. Jakie wartości może mieć Maybe lub Vector bez sparametryzowania na typie? Możesz być skłonny myśleć, że Maybe może mieć wartość Nothing, ale Nothing jest wpisany jako:

Prelude> :t Nothing 
Nothing :: Maybe a 

Klucz Jako, że Nothing może być dowolnyMaybe a, ale to musi jeszcze a wiedzieć to Nothing. (To trochę tak, gdybym powiedział ci "przynieś mi kieliszek" zamiast "przynieś mi szklankę czegoś" - nie możesz ważnie przestrzegać, dopóki przynajmniej nie skończę mojej myśli).

Można z pewnością create częściowo stosowana funkcje który zwróci kompletny typ raz są one stosowane:

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

Istnieje już konstruktor T1 i jest nazwany Vector:

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

Spowoduje to utworzenie konstruktora typu dla Vector Int. Zauważ, że tutaj Vector jest używany jako konstruktor typu, ponieważ podajesz argument typu.Można kwerendy rodzaju typu T1 z :k:

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

Ten mówi, że T1 jest konstruktorem typu, który zajmuje rodzaj betonu (*) i zwraca typ betonu.

Aby utworzyć dane konstruktora, trzeba zapewnić danych wartość pierwszego parametru danych z Vector konstruktor:

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

(Zauważ, że Vector jest zarówno rodzaj * Konstruktor i konstruktor danych, ponieważ użyto tej samej nazwy po lewej i prawej stronie deklaracji data.)

Powiązane problemy