2013-03-08 13 views
8

Bawię się próbując zrozumieć zajęcia w Haskell. Napisałem głupie kilka linijek kodu, aby się zawiesić. Napisałem klasę o nazwie Slang, która ma jedną funkcję. Kiedy robię Integer instancją mojej klasy, działa dobrze. Ale gdy ustawię String jako instancję mojej klasy, nie skompiluję. Ja już się wierciłem programem w oparciu o to, co mówi mi wynik błędu, ale bez skutku. Mam pojęcia, dlaczego to działa ...Nie można uczynić String instancją klasy w Haskell

Oto kod błędu następuje:

module Practice where 

class Slang s where 
    slangify :: s -> String 

instance Slang Integer where 
    slangify int = "yo" 

instance Slang String where -- When I take this segment out, it works fine 
    slangify str = "bro" 

BŁĄD:

Prelude> :load Practice 
[1 of 1] Compiling Practice   (Practice.hs, interpreted) 

Practice.hs:9:10: 
    Illegal instance declaration for `Slang String' 
     (All instance types must be of the form (T t1 ... tn) 
     where T is not a synonym. 
     Use -XTypeSynonymInstances if you want to disable this.) 
    In the instance declaration for `Slang String' 
Failed, modules loaded: none. 
Prelude> 
+0

Tak, masz rację !! Przepraszam, naprawiłem to – CodyBugstein

Odpowiedz

12

Problemem jest to, że ciąg nie jest typ bazowy jak Integer . Co chce zrobić, to faktycznie

instance Slang [Char] where 
    slangify str = "bro" 

Jednak Haskell98 zabrania tego typu typeclass w celu utrzymania rzeczy proste i aby utrudnić ludziom pisać nakładających instancje jak

instance Slang [a] where 
    -- Strings would also fit this definition. 
    slangify list = "some list" 

W każdym razie, jak sugeruje komunikat o błędzie, możesz ominąć to ograniczenie, włączając rozszerzenie FlexibleInstances.

+3

Bezwstydna wtyczka do starego wpisu na blogu, który napisałem, badając jak preludium radzi sobie z tym ograniczeniem [w Show] (http://brandon.si/code/how-the-haskell-prelude-avoids-overlapping- typy-w-show /). – jberryman

+1

@jberryman: Cool. Nie przestałem o tym myśleć. – hugomg

+0

Jak włączyć FlexibleInstances? – CodyBugstein

5

Zrobiłem trochę badań w mojej literaturze Haskell (aka moja aktualna Biblia) i znalazłem przykład, który skutecznie rozwiązuje mój problem.

Zasadniczo w tego obejścia ustawić Char być instancją klasy (na przykład książki to się nazywa Visible), a następnie można ustawić [chars] aka String, być instancją klasy, jak również tylko z zastrzeżenie, że zmienna typu chars jest instancją `Visible '. Łatwiej jest zrozumieć, jeśli spojrzeć na poniższy kod:

module Practice where 

class Visible a where 
    toString :: a -> String 
    size :: a -> Int 

instance Visible Char where 
    toString ch = [ch] 
    size _ = 1 

instance Visible a => Visible [a] where 
    toString = concat . map toString 
    size = foldr (+) 1 . map size 

Moja GHCi obciążenia i wywołanie funkcji:

*Practice> :l Practice 
[1 of 1] Compiling Practice   (Practice.hs, interpreted) 
Ok, modules loaded: Practice. 
*Practice> size "I love Stack!" 
14 
*Practice> 

Eureka!

Powiązane problemy