[英]calling function after input in haskell
这是家庭作业的一部分。 我需要编写一个从输入读取信息直到空行的函数。 在该函数之后,将第一,第三,第五...行符号作为一个字符串,将第二,第四...作为另一字符串。 签名combine :: IO (String , String)
我编写了一个函数,该函数将列表作为参数,并将1,3,5 ..放在一个String
将2,4,6个符号放在另一个String
。 功能在这里:
intotwo (x : xs)
= let
(us , vs)
= intotwo xs
in
(x : vs , us)
intotwo _
= ([] , [])
我还编写了一个读取输入的代码:在这里:
combine
= do
lines <- getLine
if null lines
then return ([], [])
else do
linesagain <- combine
return --what should I return?
有人可以帮我完成作业吗(可选:提供一些技巧)?
我会给您一些提示,以帮助您解决问题。
首先,为您定义的所有函数提供类型是一个巨大的帮助。 这使编译器可以立即告诉您函数是否没有按照您认为的那样做。 当您需要将程序的不同部分连接在一起时,它也可以为您提供帮助。
其次,每个功能仅解决一个问题是一个很好的主意。 您的intotwo函数很好地遵循了这一点,它很好地完成了拆分列表的工作。 但是,您的Combine函数似乎正在尝试做太多事情,这将使编写变得更加困难。 我会将那个功能分成两个较小的功能。
最后,有一个非常有用的特殊函数,称为undefined
。 这可以匹配任何类型,并有助于您编写函数。 诀窍是从整个函数等于未定义开始(并且编译但在运行时崩溃),并逐步改进该函数,直到它完成您想要的操作并且其中没有更多未定义为止。
因此,首先,我将一个类型签名添加到intwo函数中。 类型是[a] -> ([a], [a])
。
接下来,我将编写一个函数,该函数从输入中读取行,直到遇到空行,然后返回读取的行的列表。 该函数的类型为:
readLinesUntilEmpty :: IO [String]
readLinesUntilEmpty = undefined
一个几乎可以做到这一点的实现是这样的:
readLinesUntilEmpty = do
nextLine <- getLine
rest <- readLinesUntilEmpty
return (nextLine : rest)
但是,这永远不会停止读取(请注意如何不检查nextLine是否为空)。
以下函数显示了如何执行此操作(但我省略了一些实现):
readLinesUntilEmpty = do
nextLine <- getLine
case nextLine of
"" -> do
undefined -- TODO fix me
_ -> do
undefined -- TODO fix me
您应该能够从那里找出其余的内容。
接下来,您的intotwo函数将返回两个字符串列表,但是希望您将它们再次结合在一起。 例如["this", "that"]
应该变成"this\\nthat"
。 此类函数的类型为[String] -> String
:
joinLines :: [String] -> String
joinLines = undefined -- TODO
这个函数比inttotwo函数更容易编写,因此应该没问题。
最后,您可以将这三个功能链接在一起以获得结果:
combine :: IO (String, String)
combine = do
lines <- readLinesUntilEmpty
let (oddLines, evenLines) = intotwo lines
return $ (joinLines oddLines, joinLines evenLines)
由于需要读取多个字符串,因此需要递归输入。 或者,您可以只使用getContents,但是我不确定它是否适合交互式I / O。 像这样:
combine = getContents
>>= return . intotwo
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.