假设一个函数“获取”一个信息序列(例如一个字符列表),并且应该从中创建不同的类型,其中它的类型取决于输入序列,它表示内容 - 并假设类型已经给出。
numFromString :: [Char] -> ???
Run Code Online (Sandbox Code Playgroud)
我想有几种可能性。
我的第一个想法是使用类型参数。
main :: IO ()
main =
do
sLine <- getLine
print $ numFromString sLine
numFromString :: (Show a, Read a) => String -> (Maybe a)
numFromString ('I':'n':'t':'e':'g':'e':'r':rs) = Just ((read rs) :: Integer)
-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ this does not work
numFromString ('I':'n':'t':rs) = Just ((read rs) :: Int)
numFromString _ = Nothing
Run Code Online (Sandbox Code Playgroud)
...但我们不能只提供一个 Integer 类型变量,或者我们可以吗?。
我的第二个想法是使用类型类
main :: IO ()
main =
do
sLine <- getLine
print $ ((numFromString sLine) :: …
Run Code Online (Sandbox Code Playgroud) 我创建了一系列流程“步骤”,这些步骤的实施方式使得可以尽早输出信息。
例如
mainFromSettings :: Settings -> IO ()
...
mainFromSettings ... =
do
Sys.setInputEcho False
Sys.hSetBuffering Sys.stdout Sys.NoBuffering
sContent <- getContents
let
records :: [[String]]
records = Rcr.fromContent rcrConfig sContent
...
print records
Run Code Online (Sandbox Code Playgroud)
每次从惰性 IO 流“sContent”构建记录时,上面的代码片段都会打印一条记录。
我想这是这样工作的,因为一旦输入一行,“打印记录”就会占据准备打印的列表的头部。我还假设当列表的顺序相反时这将不起作用。
不幸的是,在其中一个流程步骤中它并不是这样工作的。对于此流程步骤,在显示单个字符之前,记录列表必须完整。该函数的不同之处在于一个额外的 IO 函数,它为每条记录提供额外的信息。
为了理解这个问题,我创建了以下代码来模拟这个额外的 IO 功能。该代码还模仿已经可用的记录(以避免与打开句柄有关的冲突)。
import qualified System.IO as Sys
import qualified System.IO.Echo as Sys
main :: IO ()
main =
Sys.setInputEcho False >>
Sys.hSetBuffering Sys.stdout Sys.NoBuffering >>
Sys.hSetBuffering Sys.stdin Sys.NoBuffering >>
checkAll ["12","34","56"] >>=
print
checkAll :: [String] -> IO [String] …
Run Code Online (Sandbox Code Playgroud) 背景:我正在开发一个声明式编译器。在本课程中,我将编写一个类来构建一个中间数据结构。构建数据结构后,可以从数据结构重新渲染输出。为了简化 stackoverflow,我创建了以下代码:
module Main where
import qualified Data.Word as W
import qualified Octetable as Oct
main :: IO ()
main =
do
print (buildNRender "123")
data MyData = MyData Integer
data Construction model = Contains model | Error String
deriving Show
class Builder g where
build :: String -> (Construction g)
render :: (Construction g) -> [W.Word8]
buildNRender :: String -> [W.Word8]
buildNRender = render . build
instance Builder MyData where
build s = Contains (MyData (read s :: Integer)) …
Run Code Online (Sandbox Code Playgroud)