我开始学习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!!!
- 使用适当的括号修改代码,至少在我认为它们去的地方。
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
我将'let'表达式放在块的外部,我不相信它会进入内部,如果我这样做,我也会收到解析错误。不对,但我想我还是会问。
答案 0 :(得分: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
块不能出现在顶层,它们只出现在另一个定义中。您在GHCi中使用let
但其原因超出了本答案的范围。可以说在GHCi中输入表达式并不等同于源文件的顶级。
接下来,如果你在某个地方使用let
块,它只能包含定义。语法看起来更像
let <name> [<args>] = <definition>
[<name> [<args>] = <definition>]
in <expression>
这整个块表达了。例如,你可以写
def f(x, y, z):
w = x + y + z
u = x - y - z
return w * u
在Python中,这相当于Haskell函数定义
f x y z = let w = x + y + z
u = x - y - z
in w * u
它只定义局部变量。当您在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
请注意,此处无需使用in
。你可以根据需要,只是意味着你必须开始一个新的do
块:
main = do
name <- getLine
let message = ...
goodbye n = ...
in do
putStrLn message
goodbye name
这并不是那么漂亮。
希望这会使您更加注重正确的语法,但看起来您对Haskell的工作方式存在一些误解。你看过Learn You a Haskell吗?它是一种非常温和而有趣的语言介绍,可以真正帮助您学习语法和核心思想。
答案 1 :(得分:1)
您的解析错误来自let
关键字。删除它,不会发生与此相关的错误。 let x = y
仅与GHCi和do
- 块有关,此时两者都不相关。基本上,只需用这一行替换它:
theWordIGet = stutter 6 "Iwannabehere"
其次,Haskell中的instance
关键字 absolutley nothing 与您在此阶段要执行的操作有关。这不是Haskell函数的定义方式,而是我猜你想做的事情。这是您想要创建stutter
函数的假设,假设它只是重复字符串n
次。
stutter :: Int -> String -> String
stutter n x = concat (replicate n x)
您还要删除(超出范围)值n
和x
的类型声明:它们不是对象,它们是&#d;函数的参数,它有自己的签名,用于确定函数调用中n
和x
的类型。
最后,我想你会在程序执行时打印stutter 6 "Iwannabehere"
的值。要做到这一点,只需添加:
main :: IO ()
main = print (stutter 6 "Iwannabehere")
总之,我恳求你从头开始并阅读“了解你的哈斯克尔”#39;在线here,因为您完全走错了方向 - 您引用的程序是可以具有意义的混乱表达,但是在错误的地方。本书将向您展示Haskell的语法,我在这一个答案中可以写得更好,并将完全解释如何使您的程序以您期望的方式运行。