2015-03-16 13 views
6

ich ein Anfänger-Coder in Haskell bin, während eine Übung aus dem ersten Kapitel dieses erstaunliche Buch tun: http://book.realworldhaskell.org/read/getting-started.html ich auf diese Frage kam:Haskell verschachtelt, wo Klauseln

-- 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’ 

Warum kann ich nicht verschachtelt meine wheres ?

+0

Unabhängig davon ist "interagieren" praktisch nie der richtige Weg, um I/O in Haskell zu tun. – dfeuer

+2

@dfeuer: es ist nichts falsch daran, 'interact' für simple" Ich möchte nur diese Haskell-Funktion in der Shell haben "-Kind von Programmen. Natürlich ist 'String' immer ineffizient, aber für viele solcher Anwendungen ist das völlig egal. – leftaroundabout

+3

@dfeuer Ich stimme zu, ich mache nur diese Übung mit dem vorhandenen Text aus dem Buch, ich habe nicht die Art von Know-how erreicht, die Sie in Haskell haben, aber ich verstehe gutes Design und vor allem in späteren Phasen des Buches werde ich lerne den "richtigen Weg" danke für den Kommentar obwohl – user1639848

Antwort

7

Da Ihre zweite where an die wordCount Definition angehängt ist, muss sie mehr eingerückt werden. (. Auch wenn Sie noch später einige andere Fehler haben)

+0

vielen dank, ich reparierte es – user1639848

2

die Einbuchtung war falsch, hier ist die Arbeitsversion:

-- 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

Andere haben bereits beantwortet. Ich werde nur etwas mehr Erklärung hinzufügen.

Vereinfachen ein wenig, die Haskell Einbuchtung Regel lautet:

  • Einige Schlüsselwörter beginnen einen Block von Dingen (where, let, do, case ... of).
  • Suchen Sie das erste Wort nach solchen Schlüsselwörtern und notieren Sie den Einzug. Benennen Sie die Spalte, in der die Pivot-Spalte auftritt.
  • Starten Sie eine Linie genau auf dem Drehpunkt, um einen neuen Eintrag im Block zu definieren.
  • Starten Sie eine Linie nach dem Drehpunkt, um den in den vorherigen Zeilen begonnenen Eintrag fortzusetzen.
  • Eine Zeile vor dem Drehpunkt beginnen, um den Block zu beenden. Daher

,

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

bedeutet eigentlich

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 
     } 
    } 

die den zweiten where als separate Definition in keinem Zusammenhang mit wordCount behandelt. Wenn wir es mehr einrücken:

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