在Haskell中无法将IO字符串转换为[Char] [英] Couldn't convert an IO String to [Char] in Haskell
问题描述
我编写了一个简单的函数,它使用两个文件名(字符串),并将第一个文件的内容写入第二个文件,对每个字符应用 toUpper
.
I wrote this simple function that takes two file names (String) and wrote the content of the first file into the second file applying toUpper
to each character.
import Data.Char
ioFile f1 f2 = do
s <- readFile f1
sUp <- [toUpper c | c <- s]
writeFile f2 sUp
但是口译员提出了错误
Couldn't match expected type ‘IO String’ with actual type ‘[Char]’
In a stmt of a 'do' block: sUp <- [toUpper c | c <- s]
In the expression:
do { s <- readFile f1;
sUp <- [toUpper c | c <- s];
writeFile f2 sUp }
In an equation for ‘ioFile’:
ioFile f1 f2
= do { s <- readFile f1;
sUp <- [toUpper c | c <- s];
writeFile f2 sUp }
如何将 s
用作 [Char]
,而不是 IO String
?
推荐答案
第二行不是IO Monadic操作,它只是列表理解,因此应将其编写为:
The second line is not an IO Monadic operation, it is simply list comprehension, so you should write it as:
import Data.Char
ioFile f1 f2 = do
s <- readFile f1
writeFile f2 [toUpper c | c <- s]
Haskell社区的重要组成部分,但是考虑做
有害,因此更希望看到:
A significant part of the Haskell community however considers do
harmful and thus would prefer to see:
ioFile f1 f2 = readFile f1 >>= \s -> writeFile f2 $ map toUpper s
或更短:
ioFile f1 f2 = readFile f1 >>= writeFile f2 . map toUpper
带有 map::(a-> b)->[a]->[b]
您可以将给定函数(在本例中为 toUpper
)应用于给定列表的每个元素,并生成结果列表.(>> =):: Monad m =>m a->(a-> m b)->m b
非正式地等同于在左单子的结果"上调用给定的右操作数函数.因此 c>> = f
等效于:
with map :: (a -> b) -> [a] -> [b]
you apply the given function (in this case toUpper
) to every element of the given list and generate a list of results. (>>=) :: Monad m => m a -> (a -> m b) -> m b
informally is equivalent to calling the given right operand function on the "result" of the left monad. So c >>= f
is equivalent to:
do
x <- c
f x
这篇关于在Haskell中无法将IO字符串转换为[Char]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!