2011-09-27 14 views
11

Próbuję utworzyć pierścień Z/n (jak normalna arytmetyczna, ale modulo jakaś liczba całkowita). Przykładowym przykładem jest Z4:Konstruktor danych w szablonie haskell

instance Additive.C Z4 where 
    zero = Z4 0 
    (Z4 x) + (Z4 y) = Z4 $ (x + y) `mod` 4 

I tak dalej za pierścionek. Chciałbym móc szybko wygenerować te rzeczy i myślę, że sposobem na to jest szablon haskell. Idealnie chciałbym po prostu przejść $(makeZ 4) i wypluć kod dla Z4, jak to zdefiniowałem powyżej.

Mam jednak wiele problemów z tym. Kiedy wykonuję genData n = [d| data $n = $n Integer] pojawia się "błąd parsowania w deklaracji danych/typów". Działa to, jeśli nie używam zmiennych: [d| data Z5 = Z5 Integer |], co musi oznaczać, że robię coś dziwnego ze zmiennymi. Nie jestem pewien co; Próbowałem konstruować je za pomocą newName i to też nie działa.

Czy ktoś może mi pomóc z tym, co się tutaj dzieje?

+0

Nie jestem kretynem szablonów Haskella, ale założę się, że ludzie, którzy będą chcieli, zobaczą twój szablon Haskella. –

Odpowiedz

13

Zestaw Template Haskell documentation zawiera listę rzeczy, które możesz połączyć.

Spoina może wystąpić w miejscu

  • ekspresyjnym; splicowane wyrażenie musi mieć typ; wyrażenie złożone po splicingu musi mieć listę deklaracji najwyższego poziomu; splecionych wyrażenie musi mieć typ Q [Dec]

w obu wystąpień $n jednak starasz się splatać się nazwę.

Oznacza to, że nie można tego zrobić, korzystając z ofert i splotów. Będziesz musiał zbudować deklarację za pomocą różnych kombinatorów dostępnych w module Language.Haskell.TH.

Myślę, że to powinno być równoważne z tym, co próbujesz zrobić.

genData :: Name -> Q [Dec] 
genData n = fmap (:[]) $ dataD (cxt []) n [] 
          [normalC n [strictType notStrict [t| Integer |]]] [] 

Tak, to trochę brzydkie, ale proszę bardzo. Aby z niego skorzystać, zadzwoń na to ze świeżą nazwą, np.

$(genData (mkName "Z5")) 
+0

Czy możesz podać przykład jego użycia? Zmodyfikowałem to, co miałeś i właśnie rzuciłem '$ (genData" Foo ")' jako najwyższy poziom w moim kodzie, ale jeśli zrobię ': i Foo' w ghci, to nic nie znajdzie. – Xodarap

+1

@Xodarap: Użyj 'mkName', aby utworzyć' Name' z 'String'. Dodałem przykład. Domyślam się, że użyłeś 'newName', które dodaje trochę rzeczy na końcu, aby upewnić się, że nazwa jest unikalna, więc': info' nie wyświetliłoby tego. Powinieneś być w stanie to zobaczyć, używając ': browse'. – hammar

+0

Dzięki! to był dokładnie mój problem. – Xodarap

Powiązane problemy