2015-03-16 11 views
6

Jestem koder Początkujący w Haskell, robiąc ćwiczenia z pierwszym rozdziale tej niesamowitej książki: http://book.realworldhaskell.org/read/getting-started.html natknąłem tym numerze:Haskell zagnieżdżone gdzie klauzule

-- test comment 
main = interact wordCount 
where 
    wordCount input = show (ls ++ " " ++ ws ++ " " ++ cs ++ "\n") 
    where 
     ls = lines input 
     ws = length words input 
     cs = length input 



wonderbox:ch01 manasapte$ runghc WC < quux.txt 
WC.hs:5:9: parse error on input ‘where’ 

Dlaczego nie można zagnieżdżać moi wheres ?

+0

Niepowiązanie z "interakcją" praktycznie nigdy nie jest właściwym sposobem na wykonanie operacji we/wy w Haskell. – dfeuer

+2

@dfeuer: nie ma nic złego w korzystaniu z 'interakcji' dla prostego" Po prostu chcę mieć tę funkcję Haskella w powłoce "-rind programów. Oczywiście "String" jest zawsze nieefektywny, ale dla wielu takich aplikacji zupełnie nie ma znaczenia. – leftaroundabout

+3

@dfeuer Zgadzam się, właśnie robię to ćwiczenie z istniejącym szablonem z książki, nie osiągnąłem takiego poziomu wiedzy, jak w haskell, ale rozumiem dobry projekt, a głównie na późniejszych etapach książki. ucz się "właściwej drogi", dziękując za komentarz: – user1639848

Odpowiedz

7

Ponieważ twój drugi where jest dołączony do definicji wordCount, musi być wcięty bardziej niż on. (. Mimo, że będzie jeszcze jakieś inne błędy później)

+0

wielkie dzięki, naprawiłem to – user1639848

2

wcięcie było nieprawidłowe, oto wersja robocza:

-- test comment 
import Data.List 
main = interact wordCount 
    where wordCount input = unlines $ [concat $ intersperse " " (map show [ls, ws, cs])] 
      where ls = length $ lines input 
        ws = length $ words input 
        cs = length input 
5

Inni już odpowiedział. Dodam tylko trochę wyjaśnienia.

Upraszczając nieco, reguła wcięcie Haskell jest:

  • Niektóre słowa kluczowe uruchomić blok rzeczy (where, let, do, case ... of).
  • Znajdź pierwsze słowo po takich słowach kluczowych i zanotuj jego wcięcie. Nazwij kolumnę, w której występuje kolumna przestawna.
  • Rozpocznij linię dokładnie na osi przestawnej, aby zdefiniować nowy wpis w bloku.
  • Rozpocznij linię po osi przestawnej, aby kontynuować wpis rozpoczęty w poprzednich wierszach.
  • Rozpocznij linię przed pivotem, aby zakończyć blok.

Stąd

where 
    wordCount input = show (ls ++ " " ++ ws ++ " " ++ cs ++ "\n") 
    where 
     ls = lines input 
     ws = length words input 
     cs = length input 

rzeczywistości oznacza

where { 
    wordCount input = show (ls ++ " " ++ ws ++ " " ++ cs ++ "\n") 
    ; 
    where {  -- same column, new entry 
     ls = lines input 
     ; -- same column, new entry 
     ws = length words input 
     ; -- same column, new entry 
     cs = length input 
     } 
    } 

który traktuje drugą where jako oddzielny określenia niezwiązanego z wordCount. Jeśli przytoczymy więcej:

where { 
    wordCount input = show (ls ++ " " ++ ws ++ " " ++ cs ++ "\n") 
     where {  -- after the pivot, same entry 
     ls = lines input 
     ; 
     ws = length words input 
     ; 
     cs = length input 
     } 
    }