File 保存haskell之前按长度筛选文件
有人问了一个类似的问题,但手头有一份清单: 我已经知道如何从文件中获取单词列表File 保存haskell之前按长度筛选文件,file,haskell,filter,File,Haskell,Filter,有人问了一个类似的问题,但手头有一份清单: 我已经知道如何从文件中获取单词列表 getWords path = do contents <- readFile path return (lines contents) getWords path=do contents我不确定我是否完全理解这个问题。它围绕着“在将其保存为单词列表之前”的概念展开,这在一种懒惰的语言中似乎具有误导性。在哈斯克尔,你在做什么 let list1 = someLongLi
getWords path = do contents <- readFile path
return (lines contents)
getWords path=do contents我不确定我是否完全理解这个问题。它围绕着“在将其保存为单词列表之前”的概念展开,这在一种懒惰的语言中似乎具有误导性。在哈斯克尔,你在做什么
let list1 = someLongList
list2 = filter p list1
in use list2 -- (but do not use list1)
不会导致list1
完全存储在内存中:相反,不满足p
的元素将立即被丢弃。
因此,在“保存”列表之前过滤列表的概念没有意义:这是编译器将为您执行的标准优化
相反,分离输入/输出和过滤是首选方法。另一种方法,即在代码中混合I/O和纯计算,通常被认为是更糟糕的方法。Haskell类型也鼓励第一种更简单的方法。我不确定我是否完全理解这个问题。它围绕着“在将其保存为单词列表之前”的概念展开,这在一种懒惰的语言中似乎具有误导性。在哈斯克尔,你在做什么
let list1 = someLongList
list2 = filter p list1
in use list2 -- (but do not use list1)
不会导致list1
完全存储在内存中:相反,不满足p
的元素将立即被丢弃。
因此,在“保存”列表之前过滤列表的概念没有意义:这是编译器将为您执行的标准优化
相反,分离输入/输出和过滤是首选方法。另一种方法,即在代码中混合I/O和纯计算,通常被认为是更糟糕的方法。Haskell类型也鼓励第一种更简单的方法。使用IO
也是函子的一个实例这一事实
filteredWords <- fmap (filter (\x -> length x == 3)) $ getWords path
我认为readFile
在Prelude
中,如果不是,那么它将在系统中。IO
使用IO
也是Functor
的一个实例这一事实
filteredWords <- fmap (filter (\x -> length x == 3)) $ getWords path
我认为readFile
在Prelude
中,如果不是,那么它将在System.IO中。下面是一个使用pipes
的示例,它可以避免实现完整的单词列表。只有指定长度的字将保留在内存中:
import Pipes
import qualified Pipes.Prelude as Pipes
import qualified System.IO as IO
filteredWords :: FilePath -> IO [String]
filteredWords path =
IO.withFile path IO.ReadMode (\handle -> Pipes.toListM (
Pipes.fromHandle handle >-> Pipes.filter (\x -> length x == 3) ))
例如,如果您的文件有1000000个单词,但其中只有4个单词的长度为3,那么这个程序将只生成长度为4的列表。所有其他元素在读取后会立即被丢弃,不会存储在某个中间列表的内存中。是。下面是一个使用pipes
的示例,它可以避免实现完整的单词列表。只有指定长度的字将保留在内存中:
import Pipes
import qualified Pipes.Prelude as Pipes
import qualified System.IO as IO
filteredWords :: FilePath -> IO [String]
filteredWords path =
IO.withFile path IO.ReadMode (\handle -> Pipes.toListM (
Pipes.fromHandle handle >-> Pipes.filter (\x -> length x == 3) ))
例如,如果您的文件有1000000个单词,但其中只有4个单词的长度为3,那么这个程序将只生成长度为4的列表。所有其他元素在读取后会立即被丢弃,不会存储在内存中的某个中间列表中。在“filteredWords Before”之前,filteredWords这一个短而甜美,与我已有的getWords完美结合。如果不使用getWords(仍然是一行),我会等待更多的答案,如果没有,我会接受这个答案。这个答案简短而甜美,与我已有的getWords完美结合。如果不使用getWords(仍然是一行),我会等待更多的答案,如果没有,我会接受这个答案。FWIW,(行内容)
是行列表,而不是单词。FWIW,(行内容)
是行列表,而不是单词。