Haskell IO(字符串)和字符串
我想编写函数并将结果放入字符串 我想要功能:Haskell IO(字符串)和字符串,haskell,input,io,Haskell,Input,Io,我想编写函数并将结果放入字符串 我想要功能: read' :: FilePath -> String 我使用: :t readFile readFile :: FilePath -> IO String 我提出: read' :: IO () read' = do str <- readFile "/home/shk/workspace/src/test.txt" putStrLn str 那为什么我不能: read' :: String read'
read' :: FilePath -> String
我使用:
:t readFile
readFile :: FilePath -> IO String
我提出:
read' :: IO ()
read' = do
str <- readFile "/home/shk/workspace/src/test.txt"
putStrLn str
那为什么我不能:
read' :: String
read' = do
str <- readFile "/home/shk/workspace/lxmpp/src/test.txt"
str
read'::字符串
读“=do
str如果希望它返回str
,而不是()
,则应在read'
中使用return str
。您不能从read'
类型中删除IO
,因为它不是一个纯函数。为了更好地掌握Haskell中输入/输出的工作原理,我推荐您。更详细的原因是:它允许杂质
您绝对不能在纯操作期间执行IO,否则会完全破坏引用透明性。从技术上讲,您可以使用unsafePerformIO
,但在这种情况下,它会破坏引用的透明度-只有在能够保证结果始终相同的情况下,您才应该使用它。只是为了再多吹毛求疵一点,而其他答案是完全正确的,我想强调一点:类型为IO String
的内容不仅仅是类型系统无法直接获取的字符串。它是一种执行I/O以获取字符串的计算。将readFile
应用于文件路径不会返回String
值,就像将牛排放在绞肉机旁边会神奇地将它们变成汉堡包一样
当您有如下代码时:
foo = do let getStr = readFile "input.txt"
s1 <- getStr
s2 <- getStr
-- etc.
foo=do让getStr=readFile“input.txt”
s1我认为还没有人回答这个非常重要的问题:
我想问str是不是字符串
我会尽力的
变量str
的类型为String
,是。
然而,这个变量的范围非常有限。我认为去除do符号对于理解以下内容是必要的:
read' = readFile "/home/shk/workspace/src/test.txt" >>= (\str -> putStrLn str)
我想在这里,我们可以更清楚地看到为什么str
不够好。它是传递给>=
的函数的参数。它的值只有在有人调用您的函数时才可用,这只有在执行包含它的IO
操作时才会发生
另外,read':IO()
的类型不是由putStrLn str
决定的,而是由操作符>=
的返回类型决定的。看看它(专门用于IO
monad):
您可以看到,结果总是一个iob
操作,因此尝试更改任何参数都没有帮助
如果你想了解为什么是这样的类型,你可以阅读一些monad教程。它背后的直觉是:不执行动作就不能执行动作
在问题的实际方面,使用某个操作返回的值,而不是尝试执行use(extractValue inputation)
,这是没有意义的,因为extractValue
是不可能的,如果use
确实涉及I/O,请尝试使用inputation>=use
,或者fmap使用inputAction
,如果没有。do符号中的readFile表示您在IO单子中,并且IO单子无法转义@is7s,除非您使用unsafePerformIO
!不安全的第一条规则是你不能告诉任何人关于不安全的事@托马斯,呃,哦,就像现实世界中的哈斯凯尔打破了那样rule@Thomas除非他理解广义的预组对称性,否则这是正确的,请注意,与绑定没有任何意义,是否保证结果足够相同以声称纯度?我的意思是,unsafePerformIO(putStrLn“hello!”)
能被称为纯吗?@Rotsor:别忘了它也必须是线程安全的。手动保证纯度是困难的@camccann我不知道如何解释你的评论。你是在扩展用户定义的一元纯度的概念,还是在暗示实现它的实际困难?如果不扩展,它可以通过,比如说,safePerformIO=unsafePerformIO::IO()->()
,来实现,对吗?这是不好的。。。还是不?@罗特:啊,对不起,不清楚。我用“不,这还不够”来回答你的问题,并添加了一个额外的要求,即即使它使用的是ST
-样式包含杂质,它也必须独立于可能的并发资源访问。在<>代码> unSimePrimeIO/COD>存在的情况下确保纯度确实是非常非常困难的。但是,是的,这通常是一个信号,表明它并不纯粹。基本上,你不应该在意是否使用了之前计算的值。神奇汉堡的好处是你可以吃它们而不用担心副作用!
foo = do let getStr = readFile "input.txt"
s1 <- getStr
s2 <- getStr
-- etc.
read' = readFile "/home/shk/workspace/src/test.txt" >>= (\str -> putStrLn str)
(>>=) :: IO a -> (a -> IO b) -> IO b