交互式程序

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
交互式程序
• Haskell如何处理具有副作用的输入、输 出( I/O); • 基本I/O程序。 • 阅读第十八章
具有副作用的程序
• 如何编写可以读键盘和写屏幕的交互程序?例 如,“从键盘读一个串”。如果说这种操作没 有输入,输出是String,那么它不是函数,因 为每次调用的结果不同。 • 这种与外界(读写设备等)交互作用的程序具 有副作用,即程序运行的结果与外设的状态有 关系。 • Haskell 程序是数学函数,没有副作用,函数的 运行结果只依赖于它的输入。
统一动作的循环
putStr :: String IO () putStr [] = return () putStr (x:xs) = do putChar x putStr xs getLine :: IO String getLine = do x getChar if x == '\n' then return [] else do xs getLine return (x:xs)
putStrLn = putStr . (++”\n”)
一般的写动作: print :: Show a => a -> IO () print = putStrLn . show 运行一个 I/O 程序: 一个I/O程序是一个动作的描述,Hugs可以“计算” 这个动作或者执行这个动作: Main> hello Hello, World! Main>
Hint:
Represent the board as a list of five integers that give the number of stars remaining on each row. For example, the initial board is [5,4,3,2,1].
动作的结合
使用运算符>> 可以将两个动作a, b连接起来, 其 结果是先执行a,然后执行b的动作:
hello :: IO () hello = puStr “hello” >> putStr “world\n”
动作序列- do 记法
Haskell提供了一种”do notaion”以顺序连接一系列运算。例 如 hello :: IO () hello = do putStr “hello” putStr “world\n” 又如,读一组字符:
getTwo :: IO (Char, Char)
getTwo = do x <- getChar y <- getChar return (x, y)
x是getChar 返回的值
关于动作的连接
使用do记法时所有动作必须在同一列上;
ห้องสมุดไป่ตู้
每个动作返回的值可以用运算符<-取得,其 右边是动作,左边是一个变量,表示动作返回 的值。缺省情况下,动作返回的值被丢弃;
动作的类型
Haskell引入动作的类型表示交互式程序: 动作类型: IO a 类型 IO a 的元素表示完成某个 I/O 然后返回类型为 a的值 的元素。. 例如: IO Char 包含返回类型Char的动作; IO () 是返回一个值()的动作的类型,类型 () 称为单位类 型,它包含一个元素,也记作 ().或者说IO()的动作不返 回任何值。
一系列动作顺序连接的返回值类型是最后一 个动作返回值的类型。
例:提示输入一个串,并显示输入串的长度。
strlen :: IO () strlen = do putStr "Enter a string: " xs getLine putStr "The string has " putStr (show (length xs)) putStrLn " characters"
hangman :: IO () hangman = do putStrLn "Think of a word: " word sgetLine putStrLn "Try to guess it:" guess word
The action sgetLine reads a line of text from the keyboard, echoing each character as a dash:
The function diff indicates which characters in one string occur in a second string:
diff :: String String String
diff xs ys = [if elem x ys then x else '-' | x xs]
For example:
> diff "haskell" "pascal" "-as--ll"
Exercise
Implement the game of nim in Haskell, where the rules of the game are as follows:
• The board comprises five rows of stars:
读入一个整数: getInt :: IO Int getInt = do line <- getLine return (read line :: Int)
File I/O
readFile :: FilePath -> IO String writeFile :: FilePath -> string -> IO () appendFile :: FilePath -> String -> IO () where
原始动作
Prelude 包含一些基本 I/O 动作.
getChar 从键盘读一个字符,并返回所读的字符:
getChar :: IO Char
putChar c 将输入字符输出至屏幕,返回():
putChar :: IO ()
动作 return v 只返回值v,没有其他作用:
return :: a IO a
sgetLine :: IO String sgetLine = do x getCh if x == '\n' then do putChar x return [] else do putChar '-' xs sgetLine return (x:xs)
Note:
• The action getCh reads a character from the keyboard, without echoing it to the screen. • This useful action is not part of the standard library, but is a special Hugs primitive that can be imported into a script as follows:
1: 2: 3: 4: 5: * * * * * * * * * * * * * * *
• Two players take it turn about to remove one or more stars from the end of a single row.
• The winner is the player who removes the last star or stars from the board.
sumInteract :: IO () sumInteract = do putStrLn "Enter integers one per line" putStrLn "These will be summed until zero is entered" sum <- sumInts putStr "The sum was " print sum
Other Library functions
从键盘读一个串的动作: getLine :: IO String 将一个串写至屏幕:
putStr :: String -> IO ()
例如 hello :: IO () hello = putStr “Hello, World!” 写一个串并换行: putStrLn :: String -> IO ()
type FilePath = String
Hangman
实现下列游戏 hangman:
• 一个选手秘密地输入一个单词.
• 另一个选手输入一些单词设法猜出答案。 • 对于每次输入的猜测单词,计算机显示出隐蔽单词中出 现在猜测单词中的字母。 • 游戏在猜测正确时结束。
We adopt a top down approach to implementing hangman in Haskell, starting as follows:

循环的实现:输入一个 整数,直至遇到0,然后统计其和。
不断读入整数,并统计和的动作: sumInts :: IO Int
sumInts = do n <- getInt if n==0 then return 0 else (do m <- sumInts return (n+m))
注意:if表达式可以 表示一个动作,then 和else后的动作类型 必须一致,且由do 开始,除非只有一 个动作。
primitive getCh :: IO Char
The function guess is the main loop, which requests and processes guesses until the game ends.
guess :: String IO () guess word = do putStr "> " xs getLine if xs == word then putStrLn "You got it!" else do putStrLn (diff word xs) guess word
相关文档
最新文档