Haskell 哈斯凯尔不知道该怎么写;垂直项目“;

Haskell 哈斯凯尔不知道该怎么写;垂直项目“;,haskell,Haskell,我正在学习Haskell,我写这段代码是为了测试Haskell的一些概念 identifyThing :: [arg] -> String identifyThing arg = "This looks like a " ++ case arg of [] -> "empty list" [arg] -> "list" arg -> "something else" main :: IO () main = put

我正在学习Haskell,我写这段代码是为了测试Haskell的一些概念

identifyThing :: [arg] -> String
identifyThing arg = "This looks like a " ++
    case arg of
        [] -> "empty list"
        [arg] -> "list"
        arg -> "something else"

main :: IO ()
main = putStrLn (identifyThing [])
    putStrLn (identifyThing [1..10]) 
    putStrLn (identifyThing ()) 
    putStrLn (identifyThing 1)
主声明的第一行出现错误:无法将7个参数应用于putStrLn。我想这是因为我不知道如何告诉haskell,我没有把这些论点放到下一行

如果有人能告诉我我做错了什么,我将不胜感激。谢谢。

修复了它,在main之后使用“do”,再加上一个换行符,完成了这个技巧

以下是我用来让它工作的方法(也更正了程序的其他部分):


一个较长的答案是,在Haskell中,您不能将行集合在一起,期望它们按顺序工作。当您编写
do
时,它不是{}样式块或其他东西的语法,而是使用
>=
函数将行连接到更大的行中的语法。因此,当你写
do
时,实际上它只是一行:

main = putStrLn (identifyThing []) >>= \_ -> putStrLn (identifyThing [1..10]) >>= \_  -> putStrLn (identifyThing [1])
模式匹配(如
案例
或使用多个方程的等效定义)从上到下工作

Haskell的整个想法是,你不能编写垂直程序——你只能编写水平程序:),通常你可以将你的“垂直”程序重新格式化成一个较短的“水平”程序。例如

main = mapM_ (putStrLn . identifying) [[], [1..10], [1]]
是你想说的“垂直”的另一种表达“水平”的方式

对于初学者,
do
=
>
->
return
,然后学习如何使用
liftM2
Control.Monad
Control.Applicative
中的其他函数来缩短时间。此外,在许多情况下,您可以重新设计算法,这样就不再需要“垂直”代码

例如,一个易于理解的初学者代码是:

main = putStrLn (identifyThing [1..10]) >> putStrLn (identifyThing ()) >> putStrLn (identifyThing 1)

你应该移动字符串的
“a”
部分,然后写
“一个空列表”
“一个列表”
“其他东西”
,以获得正确的语法:pAlso,请注意,你的案例
[arg]->“list”
然后写
arg->“其他东西”
没有真正意义:它应该读像
[arg->“单身人士名单”
<代码>参数->“长度大于1的列表”。(类型
[a]
与值
[a]
的含义稍有不同)谢谢!不确定[x]是否对许多成员有效,还是仅对具有成员的数组有效在开始编程之前阅读haskell的教程,该教程将更清楚地解释这些概念,否则您可能会养成不良的编程习惯,这将在将来对您造成伤害。是的,我正在阅读learnyouahaskell,但我一定是在什么地方漏掉了:)
()
是一个类型为
()
的值。没什么
[()]
是一个包含一个元素的列表,即
()
。您的代码不能正确地说“其他内容”,因为类型签名
[a]->String
强制第一个参数为列表。调用类型
[arg]
是可以接受的,但会混淆两件事,所以我也改变了这一点。
main = putStrLn (identifyThing [1..10]) >> putStrLn (identifyThing ()) >> putStrLn (identifyThing 1)