解析错误:(错误的缩进或错误的括号)

dgo*_*092 -1 parsing haskell ghc

我开始学习Haskell了.即使我是一个非凡的笨蛋,我也打算做这项工作.我收到的错误列为标题.这是我编写的代码,用于尝试实现复制列表(n)次并将其新长度连接为新列表的行为.现在我基本了解了解析在Haskell中是如何工作的,在我的原始代码下面,我将给出一些修改过的代码示例,看看我对解析的理解是否足够.我现在的问题是如何正确地缩进或构造我的块以便不接收此错误(这是特定的:O) - 在创建实例和格式时,我是否缺少一些信息?如果您注意到我的当前实体或主要功能是完全错误的,请不要告诉我或提出建议.我想弄明白,并且当我到达它时将处理GHC错误.(我希望这是正确的学习方式).但是,如果我可以请求任何人的帮助来解决理解正确格式的第一个障碍,我将不胜感激.

module Main where 
import Data.List

n :: Int 
x :: [Char]

instance Data stutter n x where
   x = []
   n = replicate >>=  x : (n:xs)
   stutter >>= main = concat [x:xs]

let stutter 6 "Iwannabehere"  -- <-- parse error occurs here!!!
Run Code Online (Sandbox Code Playgroud)

- 使用适当的括号修改代码,至少在我认为它们去的地方.

module Main where 
import Data.List

n :: Int 
x :: [Char]

instance Data stutter n x where{
   ;x = []
   ;n = replicate >>=  x : (n:xs)
   ;stutter >>= main = concat [x:xs]
;
};let stutter 6 "Iwannabehere" -- there should be no bracket of any kind at the end of this
Run Code Online (Sandbox Code Playgroud)

我将'let'表达式放在块的外部,我不相信它会进入内部,如果我这样做,我也会收到解析错误.不对,但我想我还是会问.

bhe*_*ilr 5

我不确定instance Data stutter n x应该是什么,instance XYZ where语法仅用于类型类,但是这里有一些语法错误.

首先,虽然GHC表示错误已启用let stutter 6 "Iwannabehere",但您的第一个错误发生在此之前stutter >>= main = concat [x:xs].单个=符号保留用于分配,这仅仅是定义.您可以在顶层,where块内或let块内(where包括类型类实例定义)进行分配.你不能将作业作为表达式的一部分x >>= y = z.

您的下一个语法错误就是它let本身. let块不能出现在顶层,它们只出现在另一个定义中.您let在GHCi中使用但其原因超出了本答案的范围.可以说在GHCi中输入表达式并不等同于源文件的顶级.

接下来,如果您在let某处使用块,它只能包含定义.语法看起来更像

let <name> [<args>] = <definition>
    [<name> [<args>] = <definition>]
in <expression>
Run Code Online (Sandbox Code Playgroud)

这整个块表达了.例如,你可以写

def f(x, y, z):
    w = x + y + z
    u = x - y - z
    return w * u
Run Code Online (Sandbox Code Playgroud)

在Python中,这将等同于Haskell函数定义

f x y z = let w = x + y + z
              u = x - y - z
          in w * u
Run Code Online (Sandbox Code Playgroud)

它只定义局部变量.当你在do块中使用它时,还有另一种形式可以排除in <expression>部分,例如

main = do
    name <- getLine
    let message = if length name > 5 then "short name" else "long name"
        goodbye n = putStrLn ("Goodbye, " ++ n)
    putStrLn message
    goodbye name
Run Code Online (Sandbox Code Playgroud)

请注意,这里不需要使用in.你可以,如果你想,它只是意味着你必须开始一个新的do块:

main = do
    name <- getLine
    let message = ...
        goodbye n = ...
    in do
        putStrLn message
        goodbye name
Run Code Online (Sandbox Code Playgroud)

这不是很漂亮.

希望这更能指向正确的语法,但看起来你对Haskell的工作方式有一些误解.你看过Learn You a Haskell吗?这是一种非常温和而有趣的语言介绍,可以真正帮助您学习语法和核心思想.