Haskell不确定如何编写“垂直程序”

时间:2012-10-01 07:54:55

标签: 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 = putStrLn (identifyThing [])
    putStrLn (identifyThing [1..10]) 
    putStrLn (identifyThing ()) 
    putStrLn (identifyThing 1)

我在主声明的第一行收到错误:不能将7个参数应用于putStrLn。我想这是因为我不知道如何告诉haskell我没有把论据包装到下一行。

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

2 个答案:

答案 0 :(得分:7)

更长的答案是,在Haskell中,你不能将线条组合在一起并期望它们按顺序工作。当您编写do时,它不是{} - 样式块或其他内容的语法,它是使用>>=函数将行连接到更大行​​的语法。所以当你写do时,它实际上只是一行:

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

模式匹配(如case或使用多个方程的等效定义)从上到下工作。

Haskell的整个想法是你不能写垂直程序 - 你只能编写水平程序:)通常你可以将你的“垂直”程序重新编写成一个较短的“水平”程序。 E.g。

main = mapM_ (putStrLn . identifying) [[], [1..10], [1]]

是另一种说“水平”想要“垂直”说出来的方式。

对于初学者do<-return结构具有误导性。因此,您应该使用>>=>>\ ->return,然后了解如何使用<$><*>,{{1 } {},.以及liftM2Control.Monad中的其他函数。此外,在许多情况下,您可以重新设计算法,因此不再需要“垂直”代码。

对于您的示例,一个易于理解的初学者代码将是:

Control.Applicative

答案 1 :(得分:4)

修正了它,在main之后使用“do”,加上换行符,就可以了。

这是我过去的工作(也纠正了程序的其他部分):

identifyThing :: [a] -> String
identifyThing arg = "This looks like " ++
    case arg of
        [] -> "an empty list"
        [x] -> "a list with one element"
        x -> "a list with more than one element"

main :: IO ()
main = do
    putStrLn (identifyThing [])
    putStrLn (identifyThing [1..10]) 
    putStrLn (identifyThing [()])
    putStrLn (identifyThing [1])