类型为:IO字符串->;的Haskell函数;一串
我在Haskell中编写了一系列代码来创建文本索引。顶部函数如下所示:类型为:IO字符串->;的Haskell函数;一串,haskell,io,monads,readfile,Haskell,Io,Monads,Readfile,我在Haskell中编写了一系列代码来创建文本索引。顶部函数如下所示: index :: String -> [(String, [Integer])] index a = [...] 现在我想给这个函数一个从文件中读取的字符串: index readFile "input.txt" 这将不起作用,因为readFile的类型为FilePath->IO字符串 无法匹配预期的类型“字符串” 针对推断类型“IO字符串” 我看到了错误,但找不到任何类型为的函数: IO String ->
index :: String -> [(String, [Integer])]
index a = [...]
现在我想给这个函数一个从文件中读取的字符串:
index readFile "input.txt"
这将不起作用,因为readFile的类型为FilePath->IO字符串
无法匹配预期的类型“字符串”
针对推断类型“IO字符串”
我看到了错误,但找不到任何类型为的函数:
IO String -> String
我想成功的关键在于某些monad下,但我找不到解决问题的方法。你无法摆脱
IO字符串的IO
monad部分。这意味着您必须使函数返回IO[(字符串,[Integer])]
我建议您更多地了解monad,但现在您可以使用liftM
函数:
liftM index (readFile "input.txt")
liftM
具有以下签名:
liftM :: Monad m => (a -> b) -> m a -> m b
它接受一个非一元函数并将其转换为一元函数。您可以很容易地编写一个调用readFile操作的函数,并将结果传递给索引函数
readAndIndex fileName = do
text <- readFile fileName
return $ index text
没有这样的功能有很好的理由
readAndIndex fileName = do
text <- readFile fileName
return $ index text
哈斯克尔有功能纯度的概念。这意味着当使用相同的参数调用函数时,函数将始终返回相同的结果。仅允许IO的位置位于IO单子内部
如果有一个函数
index :: IO String -> String
然后我们可以通过调用,突然在任何地方执行IO操作,例如:
index (launchMissiles >> deleteRoot >> return "PWNd!")
函数纯度是一个非常有用的特性,我们不想失去它,因为它允许编译器更自由地重新排序和内联函数,它们可以在不改变语义的情况下被激发到不同的内核,这也给了程序员一种安全感,因为如果你能从函数的类型中知道函数能做什么和不能做什么
*其实有这样一个功能。它被称为unsafePerformIO
,之所以这样叫是有非常非常好的理由的。不要使用它,除非你100%确定你在做什么
或
您可能想了解monad和functor这里有一个好的monad教程:其他好的资源可以在SO中找到。只要看一下屏幕上的相关部分。我甚至会说“除非你对自己正在做的事情有200%的把握,否则不要使用它”,或者更简单的说,“不要”。我会说,unsafePerformIO的最佳用途是使用一些总是返回相同内容的过程。ie是一个标准库本机不支持的系统计算。除了我在浏览时发现的旧评论外,SO:对FFI也很有用,只是一句话:“IO monad污染了所有使用它的东西”。我确实认为这是事实,但很高兴看到它现在得到证实。谢谢^^
fmap index $ readFile "input.txt"
readFile "input.txt" >>= return . index