繁体   English   中英

Haskell 输入以创建字符串列表

[英]Haskell Input to create a String List

我想允许用户从 Haskell 中的一系列输入构建一个列表。

getLine 函数将被递归调用,直到输入停止条件(“Y”),此时返回列表。

我知道该功能需要采用与以下类似的格式。 我在分配正确的类型签名时遇到问题 - 我想我需要在某处包含 IO 类型。

getList :: [String] -> [String]
getList list =  do line <- getLine
                   if line ==  "Y"
                      then return list
                      else getList (line : list)

所以有很多事情你需要理解。 其中之一是IO x类型。 这种类型的值是一个计算机程序,当稍后运行时,它会做一些事情并产生一个类型为x的值。 所以getLine本身不做任何事情; 它仅仅某种特定类型节目。 let p = putStrLn "hello!" . 我可以多次将p序列化到我的程序中,它会打印出hello! 多次,因为IO ()是一个程序,作为一个 Haskell 恰好能够谈论和操作的值。 如果这是 TypeScript,我会说type IO<x> = { run: () => Promise<x> }并强调该 type 表示副作用动作尚未运行

那么当值是一个程序时我们如何操作这些值,例如一个获取当前系统时间的程序?

将这些程序链接在一起的最基本方法是采用一个产生x (一个IO x )的程序,然后一个 Haskell 函数,该函数采用一个x并构造一个产生y (一个x -> IO y并将它们组合起来的程序)一起形成一个产生y (一个IO y )的结果程序。这个函数被称为>>=并发音为“绑定”。事实上,这种方式是通用的,如果我们添加一个程序,该程序采用x类型的任何 Haskell 值并产生一个什么都不做并产生该值的程序( return :: x -> IO x )。例如,这允许您使用 Prelude 函数fmap f = (>>= return . f) ,它接受a -> b和将其应用于IO a以生成IO b

所以像getLine >>= \\line -> putStrLn (upcase line ++ "!")这样的东西很常见,我们发明了do -notation,把它写成

do 
    line <- getLine
    putStrLn (upcase line ++ "!")

请注意,这是相同的基本交易; 最后一行需要是一些yIO y y

在 Haskell 中你需要知道的最后一件事是实际运行这些东西的约定。 也就是说,在您的 Haskell 源代码中,您应该创建一个名为Main.mainIO () (一个值无关紧要的程序),并且 Haskell 编译器应该采用您描述的这个程序,并给出它作为可执行文件提供给您,您可以随时运行。 作为一个非常特殊的情况,GHCi 解释器会注意到您是否在顶层生成了一个IO x表达式,并会立即为您运行它,但这与语言其他部分的工作方式大不相同。 Haskell 说,在大多数情况下,请描述该程序,然后我将其提供给您。

既然您知道 Haskell 没有魔法,而 Haskell IO x类型只是作为值的计算机程序的静态表示,而不是在您“减少”它时会产生副作用的东西(就像在其他语言中一样) ),我们可以求助于您的getList 显然getList :: IO [String]根据你所说的最有意义:一个允许用户从一系列输入构建列表的程序。

现在要构建内部结构,您的猜测是正确的:我们必须从getLine开始,然后完成列表或继续接受输入,将行添加到列表中:

getList = do
    line <- getLine
    if line == 'exit' then return []
                      else fmap (line:) getList

您还确定了另一种方法,这取决于获取字符串列表并生成新列表:

getList :: IO [String]
getList = fmap reverse (go []) where 
    go xs = do 
        x <- getLine
        if x == "exit" then return xs
                       else go (x : xs)

可能还有其他几种方法可以做到。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM