2011-11-17 19 views
7

Czy ktoś wie, czy istnieje funkcja w Haskell, który robi coś takiego:Konwersja String na typ Konstruktora w Haskell

"Int" -> Int 

"String" -> String 

"Bool" -> Bool 

tj. pobiera ciąg znaków reprezentujący nazwę konstruktora typu i konwertuje go do faktycznego konstruktora typów, zarówno w wyrażeniu, jak i we wzorcu.

edit: Moim nadrzędnym celem jest uproszczenie coś takiego:

transExp (Add exp1 exp2) vars 
    = transExp exp1 vars ++ transExp exp2 vars ++ [IAdd] 

transExp (Sub exp1 exp2) vars 
    = transExp exp1 vars ++ transExp exp2 vars ++ [ISub] 

w jednym meczu wzór, więc w zasadzie konwersji Dodaj lub Sub na sznurku, dodać „ja” do przodu, i konwertować to z powrotem do typu.

+3

Czy to możliwe? Czy typy nie są koncepcją kompilacji? Jakiego rodzaju funkcji chciałbyś mieć? –

+0

Nie mam pojęcia, czy jest to możliwe, czy nie, przypuszczam, że miałoby to typ String -> a, ale nie jestem pewien ... – Jack

+0

Spójrz na szablon haskell. Również 'IAdd' nie jest typem, ale konstruktorem typu - to było mylące. – nponeccop

Odpowiedz

10

Jest to znacznie lepszy sposób byłaby kod tutaj bez jakiegokolwiek szablonu Haskell lub odbicia shenanigans po prostu łącząc swoje Add i Sub przypadków do jednego:

data BinOp = Add | Sub | ... 

data Expr = ... 
      | BinOp BinOp Expr Expr 
      | ... 

transExp (BinOp op exp1 exp2) vars 
    = transExp exp1 vars ++ transExp exp2 vars ++ [transOp op] 
... 

transOp Add = IAdd 
transOp Sub = ISub 

ten sposób używamy typ danych bezpośrednie wyrażenie faktu, że operatory binarne są powiązane i dlatego mają podobne tłumaczenia. Nadal możesz wzorzec dopasowania na BinOp Add exp1 exp2, jeśli chcesz zrobić specjalny przypadek gdzieś dodać.

+0

Cudowne rozwiązanie - o wiele mniej hacky niż to, co myślałem. Dziękuję bardzo :) – Jack

+0

To znacznie bardziej elegancko. Dziękujemy za przypomnienie, że pomożemy Ci pomniejszyć widok i uzyskać szerszy wgląd. –

2

W jakim kontekście? Jest szablon Haskell i Data.Typeable, ale aby uzyskać naprawdę pomocną odpowiedź, musisz podać więcej szczegółów.

0

Cóż, oto problem.

"String" -> String 

To bełkot w Haskell-land, ponieważ "String" jest wartością, ale String jest typem. Możesz spróbować:

String -> a 

To nie robi, co chcesz. Powinieneś nauczyć się czytać podpisy typów, ponieważ jeśli nie będziesz w stanie odczytać podpisów typu, będziesz bardzo źle utalentowany w Haskell. Powyższy typ oznacza "Podaj mi ciąg znaków i mogę podać wartość dowolnego żądanego typu." W preludii z tą sygnaturą znajduje się funkcja, która nazywa się error, co nie jest tym, czego potrzebujesz.

To brzmi jak chcesz coś wzdłuż tych linii:

String -> TypeRep 

Niestety, nie takich funkcji. TypeRep nie tworzy instancji klasy Read.

Co ty jesteś faktycznie próbujesz zrobić tutaj? Jeśli powiesz nam, co faktycznie próbujesz zrobić, możemy pomóc Ci z tym problemem, zamiast próbować pomóc w rozwiązaniu tego problemu.

+0

Nie mówi o nazwach typów, ale o konstruktorach typów. Po prostu chce wygenerować pewne wartości i dopasowania do wzorca z łańcuchów, aby uniknąć podstaw. – nponeccop

+2

@nponeccop: Nie jest sprawiedliwe udzielanie odpowiedzi po zmianie pytania. Ta firma dotycząca konstruktorów jest całkowicie nowa. –

0

Nie można tego zrobić, ponieważ ciągi są danymi wykonawczymi, a typy muszą zostać całkowicie rozwiązane podczas kompilacji. Najlepszym prawdopodobnie można zrobić ze swoim przykładzie jest funkcja pomocnika, aby wyeliminować niektóre z powielania:

helper exp1 exp2 vars op = transExp exp1 vars ++ transExp exp2 vars ++ [op] 
transExp (Add exp1 exp2) vars = helper exp1 exp2 vars IAdd 
transExp (Sub exp1 exp2) vars = helper exp1 exp2 vars ISub 

Ale to nie może być rzeczywiście bardzo przydatna w dłuższej perspektywie, w zależności od tego, ile masz przypadki.

Ogólnie rzecz biorąc, dopasowywanie wzorców jest czymś, co działa na strukturach typów, więc musi być napisane na typ kompilacji w stosunku do konstruktorów typów. Jest to cena, jaką trzeba zapłacić za posiadanie naprawdę solidnego systemu typu statycznego.

+0

Może to zrobić z szablonem kodu Haskella, który działa w czasie kompilacji – nponeccop

+0

Rzeczywiście mógł, ale w tym celu stwierdził, że wydaje mi się to nieco przesadzone. –

+0

Myślę, że musi wiedzieć o wszystkich możliwych rozwiązaniach. Jest to dla niego dobra okazja, aby dowiedzieć się, co TH może zrobić. Rozwiązanie @hammar też jest cudowne. – nponeccop