2013-04-23 13 views
5

Oto mój kod:Nie można uzyskać typu podpis praca dla prostych funkcji rekurencyjnej

test :: (Num a) => [a] -> a 
test []  = 0 
test [x:xs] = x + test xs 

Jednak kiedy go uruchomić poprzez ghci jako :l test, otrzymuję ten błąd:

[1 z 1] Kompilacja main (test.hs interpretowane)

test.hs:3:7: 
    Couldn't match type `a' with `[a]' 
     `a' is a rigid type variable bound by 
      the type signature for spew :: Num a => [a] -> a at test.hs:2:1 
    In the pattern: x : xs 
    In the pattern: [x : xs] 
    In an equation for `spew': spew [x : xs] = x + spew xs 
Failed, modules loaded: none. 

Staraj się nie śmiać :) to moja pierwsza próba Haskell. Każda pomoc lub wyjaśnienie byłoby niesamowite.

PS: Wiem, że można to łatwo zrobić z zakładką, ale staram się ćwiczyć pisanie własnych podpisów. Z góry dziękuję!!

Odpowiedz

8

To znaczy,

test :: (Num a) => [a] -> a 
test []  = 0 
test (x:xs) = x + test xs -- note round brackets 

z okrągłych nawiasach.

[x:xs] jest listą z jednego elementu, która z kolei jest lista, przy czym (x:xs) jest listą z pierwszym elementem x i ogon xs.

Po wpisaniu length (1:[1,1,1]) otrzymasz 4, ale jeśli wpiszesz length [1:[1,1,1]] otrzymasz 1 - jedynym elementem jest lista.

+1

Gah! Powinienem to zobaczyć! Dziękuję Ci! –

+0

@AthanClark Wszyscy przeżywamy to uczucie, gdy uczymy się Haskella. – Dilawar

5

Prawdopodobnie oznaczało dopasować listę jako całość, a nie pierwszym elementem listy:

test (x:xs) = ... 

Jeśli zrobisz inaczej, wzór ma wywnioskować typ [[b]], więc a == [b] według test podpis , więc xs musi mieć typ [b], więc test xs musi mieć typ b ale również wpisać a według podpisania test, co oznaczałoby, że a == [a], co stanowi sprzeczność i prowadzi do błędu zjednoczeniowego :)

+0

Niestety odpowiedź AndrewC była bardziej kompletna :) Dziękuję bardzo !!! –

Powiązane problemy